WordPress.org

Make WordPress Core

Ticket #7543: typepad.diff

File typepad.diff, 23.2 KB (added by cavemonkey50, 10 years ago)

The actual TypePad importer.

  • typepad.php

     
     1<?php
     2
     3class Typepad_Import {
     4       
     5        // General
     6        var $username;
     7        var $password;
     8       
     9        // XML parsing
     10        var $parser;
     11        var $inside_tag = '';
     12        var $active_tag = '';
     13        var $entry_tag = '';
     14        var $last = '';
     15        var $start_byte = '';
     16        var $first_child = 0;
     17        var $inside_entry = 0;
     18        var $channel = array();
     19        var $items = array();
     20        var $item = array();
     21       
     22        // The data
     23        var $posts = array();
     24        var $site_url;
     25        var $next_url;
     26        var $xmlrpc_url;
     27        var $post_count = 0;
     28        var $current_post = 0;
     29        var $first_run = true;
     30       
     31        function header() {
     32                echo '<div class="wrap">';
     33                echo '<h2>'.__('Import TypePad').'</h2>';
     34        }
     35
     36        function footer() {
     37                echo '</div>';
     38        }
     39
     40        function greet() {
     41                $this->header();
     42?>
     43<div class="narrow">
     44<p><?php _e('Howdy! We&#8217;re about to begin importing all of your TypePad entries into WordPress. To begin, enter the URL of your blog followed by the username and password of an administrator account. When you&#8217;re finished, click "Start Importing".'); ?></p>
     45
     46<form method="post" action="<?php echo add_query_arg('step', 1); ?>" class="import-upload-form">
     47
     48<?php wp_nonce_field('import-typepad'); ?>
     49<table class="form-table">
     50<tr>
     51<td><label for="mturl"><?php _e('Blog URL:') ?></label></td>
     52<td><input type="text" style="width:300px" name="mturl" id="mturl" value="http://" /></td>
     53</tr>
     54<tr>
     55<td><label for="mtuser"><?php _e('Username:') ?></label></td>
     56<td><input type="text" style="width:300px" name="mtuser" id="mtuser" value="" /></td>
     57</tr>
     58<tr>
     59<td><label for="mtpass"><?php _e("Password:") ?></label></td>
     60<td><input type="password" style="width:300px" name="mtpass" id="mtpass" value="" /></td>
     61</tr>
     62</table>
     63<p class="submit">
     64<input type="submit" value="<?php echo attribute_escape(__('Start Importing')); ?>" id="atom-submit" onclick="jQuery('#atom-loading').show();jQuery('#atom-submit').val('<?php echo attribute_escape(__('Importing...')); ?>');" /> <span style="display: none;" id="atom-loading"><img src="<?php echo get_option('home'); ?>/wp-admin/images/loading.gif" alt="Loading" style="margin-bottom: -3px;" /> <?php echo attribute_escape(__('Retrieving entries from server. Do not navigate away from this page.')); ?></span>
     65</p>
     66</form>
     67<p><?php _e('The importer is smart enough not to import duplicates, so you can run this multiple times without worry if&#8212;for whatever reason&#8212;it doesn\'t finish.'); ?> </p>
     68</div>
     69<?php
     70                $this->footer();
     71        }
     72               
     73        function detect_atom_uri($url) {
     74                // Grab the homepage
     75                $ch = curl_init();
     76                curl_setopt($ch, CURLOPT_URL, $url);
     77                curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
     78                curl_setopt($ch, CURLOPT_TIMEOUT, 5);
     79                $output = @curl_exec($ch);
     80               
     81                // Parse out the RSD URL
     82                preg_match('#<link rel="EditURI" type="application\/rsd\+xml" title="RSD" href="(.*)" \/>#i', $output, $matches);
     83               
     84                // Grab the RSD page
     85                $ch2 = curl_init();
     86                curl_setopt($ch2, CURLOPT_URL, $matches[1]);
     87                curl_setopt($ch2, CURLOPT_RETURNTRANSFER, 1);
     88                curl_setopt($ch2, CURLOPT_TIMEOUT, 5);
     89                $output = @curl_exec($ch2);
     90               
     91                // Parse out the xmlrpc URI
     92                preg_match('#<api name="MovableType" preferred="false" apiLink="([^"]*)" blogid="([^"]*)" \/>#i', $output, $xmlrpc);
     93                $this->xmlrpc_url = $xmlrpc[1];
     94               
     95                // Parse out the Atom URI
     96                preg_match('#<api name="Atom" preferred="false" apiLink="(.*)" \/>#i', $output, $matches);
     97               
     98                return $matches[1];
     99        }
     100       
     101        function fetch_atom($url, $username, $password) {
     102                include_once(ABSPATH . '/wp-admin/includes/class-atom-api.php');
     103               
     104                $atom_api = new AtomAPI($url, $username, $password, 'WSSE'); // Authenticate to the AtomPub feed using WSSE
     105                // If the login failed, throw an error message
     106                if ( ( $atom_api->err_no != '' ) && ( count($this->posts) == 0 ) ) {
     107                        $this->error();
     108                        return 'error';
     109                }
     110               
     111                 // Grab the raw feed data and pass it to the parser
     112                $this->parse_atom( $atom_api->get_feeds( $xml = false ) );
     113        }
     114       
     115        function parse_atom($xml) {
     116                // Reset the data before parsing a new feed
     117                unset($this->parser);
     118                unset($this->inside_tag);
     119                unset($this->active_tag);
     120                unset($this->channel);
     121                unset($this->items);
     122                unset($this->item);
     123                $this->inside_tag = '';
     124                $this->active_tag = '';
     125                $this->entry_tag = '';
     126                $this->last = '';
     127                $this->start_byte = '';
     128                $this->first_child = 0;
     129                $this->inside_entry = 0;
     130                $this->channel = array();
     131                $this->items = array();
     132                $this->item = array();
     133               
     134                // Create an XML parser
     135                $this->parser = xml_parser_create();
     136               
     137                // Used to make the XML parser work in a class
     138                xml_set_object($this->parser, $this);
     139               
     140                // Set the start and ending element functions           
     141                xml_set_element_handler($this->parser, "start_element", "end_element");
     142               
     143                // Set the character data functions
     144                xml_set_character_data_handler($this->parser, "character_data");
     145               
     146                // Begin parsing the XML
     147                xml_parse($this->parser, $xml)
     148                        or die(sprintf("XML error: %s at line %d", xml_error_string(xml_get_error_code($this->parser)), xml_get_current_line_number($this->parser)));
     149               
     150                // Clean up after the parse
     151                xml_parser_free($this->parser);
     152        }
     153       
     154        function start_element($parser, $element, $attrs) {
     155                switch ($element) {
     156                        case 'FEED':
     157                        case 'ENTRY':
     158                                $this->inside_tag = $element;
     159                                break;
     160
     161                        case 'CONTENT':
     162                        case 'SUMMARY':
     163                                if ( $this->inside_tag == 'ENTRY' ) {
     164                                        $this->inside_entry = 1;
     165                                        $this->entry_tag = strtolower($element);
     166                                }
     167                                break;
     168
     169                        case 'LINK' :
     170                                if ( $this->inside_tag == 'FEED' ) {
     171                                        if ( $attrs['REL'] == 'alternate' || !$attrs['REL'] ) {
     172                                                $this->_add('channel', 'link', $attrs['HREF']);
     173                                        } elseif ( $attrs['REL'] == 'next' ) {
     174                                                $this->_add('channel', 'next', $attrs['HREF']);
     175                                        }
     176                                } elseif ( $this->inside_tag == 'ENTRY' ) {
     177                                        if ( $attrs['REL'] == 'alternate' || !$attrs['REL'] ) {
     178                                                if ( $attrs['TYPE'] == 'text/html' )
     179                                                        $this->_add('item', 'link', $attrs['HREF']);
     180                                        } elseif ( $attrs['REL'] == 'service.edit' ) {
     181                                                $this->_add('item', 'link:service.edit', $attrs['HREF']);
     182                                        } elseif ( $attrs['REL'] == 'replies' ) {
     183                                                $this->_add('item', 'link:entry.comments', $attrs['HREF']);
     184                                        }
     185                                } elseif ( $this->inside_tag != 'FEED' && $this->inside_tag != 'ENTRY' ) {
     186                                        if ( $attrs['REL'] == 'next' ) {
     187                                                $this->_add('channel', 'next', $attrs['HREF']);
     188                                        }
     189                                }
     190                                break;
     191                       
     192                        case 'CATEGORY':
     193                                if ( $this->inside_tag == 'ENTRY' ) {
     194                                        $cats = array ( 'type' => $attrs['SCHEME'], 'term' => $attrs["TERM"] );
     195                                        $this->_add('item', 'categories', $cats, 1);
     196                                }
     197                                break;
     198                       
     199                        case 'AUTHOR':
     200                                if ( $this->inside_tag == 'ENTRY' ) {
     201                                        $this->inside_tag = 'ENTRY|AUTHOR';
     202                                }
     203                                break;
     204                       
     205                        case 'ALLOW':
     206                                if ( $this->inside_tag == 'ENTRY' ) {
     207                                        $this->_add('item', 'privacy', $attrs['NAME']);
     208                                }
     209                                break;
     210
     211                        default :
     212                                $this->active_tag = $element;
     213                }
     214               
     215                // Deal with tags inside of content and summary
     216                if ( $this->inside_entry && $element != 'CONTENT' && $element != 'SUMMARY' ) {
     217                        // If tags are inlined, then flatten
     218                        $attrs = array_change_key_case($attrs, CASE_LOWER);
     219                        $attrs_str = implode(' ',
     220                                array_map(array($this, 'map_attrs'),
     221                                array_keys($attrs),
     222                                array_values($attrs) ) );
     223                               
     224                        // Add a space if there are attrs
     225                        if ( $attrs_str != '' )
     226                                $attrs_str = ' ' . $attrs_str;
     227                       
     228                        // Make the element lowercase
     229                        $el = strtolower($element);
     230                       
     231                        // Close an opening tag if it had no data
     232                        if ( $this->first_child )
     233                                $this->_add('item', $this->entry_tag, ">");
     234                       
     235                        // Add the start tag
     236                        $this->_add('item', $this->entry_tag, "<$el" . "$attrs_str");
     237                       
     238                        // Handle self-closing tags
     239                        $this->first_child = 1;
     240                        $this->start_byte = xml_get_current_byte_index($parser);
     241                }
     242        }
     243       
     244        function character_data($parser, $cdata) {
     245                switch ($this->inside_tag) {
     246                        // Grab general channel information
     247                        case 'FEED':
     248                                switch ($this->active_tag) {
     249                                        case 'TITLE':
     250                                                $this->_add('channel', strtolower($this->active_tag), $cdata);
     251                                                break;
     252                                        case 'OPENSEARCH:TOTALRESULTS':
     253                                                $this->_add('channel', strtolower('fullcount'), $cdata);
     254                                                break;
     255                                }
     256                                break;
     257
     258                        // Grab item information
     259                        case 'ENTRY':
     260                                switch ($this->active_tag) {
     261                                        case 'TITLE':
     262                                                $this->_add('item', strtolower($this->active_tag), $cdata);
     263                                                break;
     264
     265                                        case 'CONTENT':
     266                                        case 'SUMMARY':
     267                                                $this->_add('item', $this->inside_tag, $cdata);
     268                                                break;
     269                                       
     270                                        case 'ISSUED':
     271                                                $this->_add('item', strtolower($this->active_tag), $cdata);
     272                                                break;
     273                                       
     274                                        case 'ID':
     275                                                $this->_add('item', strtolower($this->active_tag), $cdata);
     276                                                break;
     277                                }
     278                                break;
     279                       
     280                        // For author tags
     281                        case 'ENTRY|AUTHOR':
     282                                switch ($this->active_tag) {
     283                                        case 'NAME':
     284                                                $this->_add('item', 'author', $cdata);
     285                                                break;
     286                                        case 'URI':
     287                                                $this->_add('item', 'author_uri', $cdata);
     288                                                break;
     289                                }
     290                                break;
     291
     292                        }   
     293
     294                        // Deal with data inside content tags
     295                        if ( $this->inside_entry ) {
     296                                // Append the start tag close if first_child
     297                                if ( $this->first_child ) {
     298                                        $this->_add('item', $this->entry_tag, '>');
     299                                        $this->first_child = 0;
     300                                }
     301                               
     302                                $this->_add('item', $this->entry_tag, $cdata);
     303                        }
     304        }
     305       
     306        function end_element($parser, $element) {
     307                // Deal with tags inside of content and summary
     308                if ( $this->inside_entry && $element != 'CONTENT' && $element != 'SUMMARY' ) {
     309                        $el = strtolower($element);                     
     310                       
     311                        // Add the appropriate end tag depending if the element is a self-closing element
     312                        if ( xml_get_current_byte_index($parser) - $this->start_byte > 2 ) {
     313                                if ( $this->first_child )
     314                                        $this->_add('item', $this->entry_tag, ">");
     315                                $this->_add('item', $this->entry_tag, "</$el>");
     316                        } else {
     317                                $this->_add('item', $this->entry_tag, " />");
     318                        }
     319                        $this->first_child = 0;
     320                }
     321               
     322                // Reset inside tag back to entry for author tags
     323                if ( $element == 'AUTHOR' && $this->inside_tag == 'ENTRY|AUTHOR' ) {
     324                        $this->inside_tag = 'ENTRY';
     325                }
     326               
     327                if ( $element == $this->inside_tag ) {
     328                        $this->inside_tag = '';
     329                        $this->struct[] = array_merge(array('type' => strtolower($element)), $this->last);
     330                }
     331
     332                if ( $element == 'ENTRY' ) {
     333                        $this->items[] = $this->item;
     334                        $this->item = '';
     335                }
     336
     337                if ( $element == 'CONTENT' || $element == 'SUMMARY' ) {                 
     338                        $this->inside_entry = 0;
     339                }
     340
     341                $this->active_tag = '';
     342        }
     343       
     344        function _add($type, $field, $value, $array = 0) {
     345                if ( $array ) {
     346                        $this->{$type}[$field][] = $value;
     347                } else {               
     348                        if ( empty($this->{$type}) || empty($this->{$type}[$field]) ) {
     349                                $this->{$type}[$field] = $value;
     350                        } else {
     351                                $this->{$type}[$field] .= $value;
     352                        }
     353                }
     354
     355                $this->last = $this->{$type};
     356        }
     357       
     358        function map_attrs($k, $v) {
     359                return "$k=\"$v\"";
     360        }
     361       
     362        function get_entries() {
     363                // Set the URL
     364                if ( $this->next_url != '' )
     365                        $url = $this->next_url;
     366                else
     367                        $url = $this->detect_atom_uri(trim($_POST['mturl']));
     368       
     369                // Get the entries from the atom feed
     370                $result = $this->fetch_atom($url, $this->username, $this->password);
     371                if ( $result == 'error' ) return $result;
     372       
     373                // Set the site URL and next URLs
     374                $this->site_url = $this->channel['link'];
     375                $this->next_url = $this->channel['next'];
     376                $this->post_count = $this->channel['fullcount'];
     377               
     378                // Convert the parsed atom feed to the posts / pages array
     379                foreach ( $this->items AS $item ) {                     
     380                        $this->posts[] = $item;
     381                }
     382        }
     383       
     384        function get_comments($comment_feed) {
     385                $comments = array();
     386               
     387                // While there are more comments
     388                do {
     389               
     390                        // Select the right comments feed URL
     391                        if ( $comments_next != '' )
     392                                $comment_feed = $comments_next;                 
     393               
     394                        // Get the comments from the atom feed
     395                        if ( !empty($comment_feed) )
     396                                $this->fetch_atom($comment_feed, $this->username, $this->password);
     397                       
     398                        // The next URL
     399                        $comments_next = $this->channel['next'];
     400                       
     401                        // Convert the parsed atom feed to the comments array
     402                        foreach ( $this->items AS $item ) {                     
     403                                $comments[] = $item;
     404                        }
     405               
     406                } while ( $comments_next != '' );
     407               
     408                return $comments;
     409        }
     410       
     411        function get_trackbacks($post_id) {
     412                include_once(ABSPATH . WPINC . '/class-IXR.php');
     413               
     414                $rpc = new IXR_Client($this->xmlrpc_url);
     415                if ( !$rpc->query('mt.getTrackbackPings', $post_id) ) {
     416                //      print("Error (" . $rpc->getErrorCode() . "): ");
     417                //      print($rpc->getErrorMessage() . "\n\n");
     418                }
     419               
     420                return $rpc->getResponse();
     421        }
     422       
     423        function get_additional_data($post_id) {
     424                include_once(ABSPATH . WPINC . '/class-IXR.php');
     425               
     426                $rpc = new IXR_Client($this->xmlrpc_url);
     427                if ( !$rpc->query('metaWeblog.getPost', $post_id, $this->username, $this->password) ) {
     428                //      print("Error (" . $rpc->getErrorCode() . "): ");
     429                //      print($rpc->getErrorMessage() . "\n\n");
     430                }
     431               
     432                return $rpc->getResponse();
     433        }
     434       
     435        function process_posts() {
     436                // Start the output list if this is the first run
     437                if ( $this->first_run == true ) {
     438                        echo '<div class="wrap"><ol>';
     439                        $this->first_run = false;
     440                }
     441               
     442                // Use output buffering to show the current import progress
     443                if (ob_get_level() == 0) {
     444                    ob_start();
     445                }
     446                // Pad the page with some data so output buffering works across browsers
     447                echo str_pad('',4096);
     448               
     449                foreach ( $this->posts AS $entry ) {
     450                       
     451                        // Construct the post class from the AtomPub feed
     452                        $post = new StdClass();
     453
     454                        // The entry type (over 1 and we have a post)
     455                        if ( count(explode('/', substr($entry['link'], strlen($this->site_url)))) > 1 )
     456                                $post->post_type = 'post';
     457                        else
     458                                $post->post_type = 'page';
     459                        // The entry title
     460                        if ( isset($entry['title']) )
     461                                $post->post_title = trim($entry['title']);
     462                        else
     463                                $post->post_title = '';
     464                        // The post content
     465                        if ( isset($entry['content']) )
     466                                $post->post_content = trim($entry['content']);
     467                        // The post excerpt
     468                        if ( isset($entry['summary']) )
     469                                $post->post_excerpt = trim($entry['summary']);
     470                        // The post date
     471                        $date = strtotime(trim($entry['issued']));
     472                        $date = date('Y-m-d H:i:s', $date);
     473                        $date_gmt = get_gmt_from_date($date);
     474                        $post->post_modified = $date;
     475                        $post->post_modified_gmt = $date_gmt;
     476                        $post->post_date = $date;
     477                        $post->post_date_gmt = $date_gmt;
     478                        // The post slug
     479                        $slug = array_reverse(explode('/', trim($entry['link'])));
     480                        $slug = substr($slug[0], 0 , -5);
     481                        $post->post_name = $slug;
     482                        // The categories and tags
     483                        if ( isset($entry['categories']) ) {
     484                                foreach ( $entry['categories'] AS $cat ) {
     485                                        $post->categories[] = trim($cat['term']);
     486                                }
     487                        } else {
     488                                $post->categories = array();
     489                        }
     490                        // The post author
     491                        if ( isset($entry['author']) )
     492                                $post->post_author = trim($entry['author']);
     493                        // The post id
     494                        $post_id = trim($entry['id']);
     495                        $post_id = substr(strrchr($post_id, '-'), 1);
     496                        // The additional data
     497                        $additional_data = $this->get_additional_data($post_id);
     498                        // The comment status
     499                        if ( $additional_data['mt_allow_comments'] == 1 )
     500                                $post->comment_status = 'open';
     501                        else
     502                                $post->comment_status = 'closed';
     503                        if ( $additional_data['mt_allow_pings'] == 1 )
     504                                $post->ping_status = 'open';
     505                        else
     506                                $post->ping_status = 'closed';
     507                        // The tags
     508                        $post->post_keywords = $additional_data['mt_keywords'];
     509                        // The draft status
     510                        if ( isset($entry['privacy']) ) {
     511                                if ( $entry['privacy'] == 'Self' )
     512                                        $post->post_status = 'draft';
     513                                else
     514                                        $post->post_status = 'publish';
     515                        }
     516                       
     517                        unset($comments);
     518                        $comments = array();
     519                       
     520                        // Fetch the comments if the post has comments
     521                        $coms = $this->get_comments(trim($entry['link:entry.comments']));
     522                        if ( count($coms) > 0 ) {
     523                                foreach ( $coms AS $com ) {
     524                                        // Construct the comment class from the AtomPub feed
     525                                        $comment = new StdClass();
     526                               
     527                                        // The comment date
     528                                        $date = strtotime(trim($com['issued']));
     529                                        $date = date('Y-m-d H:i:s', $date);
     530                                        $comment->comment_date = $date;
     531                                        // The comment content
     532                                        $comment->comment_content = trim($com['content']);
     533                                        // The comment author
     534                                        $comment->comment_author = trim($com['author']);
     535                                        // The comment author uri
     536                                        $comment->comment_author_url = trim($com['author_uri']);
     537                                        // Set the unknown variables
     538                                        $comment->comment_author_email = '';
     539                                        $comment->comment_author_IP = '';
     540                               
     541                                        // Add the comment to the comments array
     542                                        $comments[] = $comment;
     543                                }
     544                        }
     545                       
     546                        unset($trackbacks);
     547                        $pings = array();
     548                       
     549                        // Fetch the trackbacks
     550                        $trackbacks = $this->get_trackbacks($post_id);
     551                        if ( count($trackbacks) > 0 ) {
     552                                foreach ( $trackbacks AS $trackback ) {
     553                                        $ping = new StdClass();
     554                                        // The ping date (the date of the post since we don't know the real one)
     555                                        $ping->comment_date = $post->post_date;
     556                                        // The ping IP address
     557                                        $ping->comment_author_IP = $trackback['pingIP'];
     558                                        // The ping URL
     559                                        $ping->comment_author_url = $trackback['pingURL'];
     560                                        // The ping author
     561                                        $ping->comment_author = $trackback['pingTitle'];
     562                                        // Set the unknow variables
     563                                        $ping->comment_author_email = '';
     564                                        $ping->comment_content = '';
     565                                        $ping->comment_type = 'pingback';
     566                               
     567                                        // Add the ping to the pings array
     568                                        $pings[] = $ping;
     569                                }
     570                        }
     571                       
     572                        $result = $this->save_post($post, $comments, $pings);
     573                        if ( is_wp_error( $result ) )
     574                                return $result;
     575                       
     576                        // Increase the post count
     577                        $this->current_post++;
     578                       
     579                        // Update the progress bar
     580                        $progress_bar = round(( $this->current_post / $this->post_count ) * 500);
     581                        $progress_percent = round(( $this->current_post / $this->post_count ) * 100, 1);
     582?>
     583<script type="text/javascript">
     584        jQuery('.progress_bar .progress_display').animate({
     585                width: "<?php echo $progress_bar; ?>px"
     586        }, 200);
     587        jQuery('.progress_percent span.percent').html('<?php echo $progress_percent; ?>');
     588        <?php if ( $progress_percent == 100 ) { ?>
     589                jQuery('.progress_percent img').hide();
     590        <?php } ?>
     591</script>
     592<?php
     593                       
     594                        // Flush the output buffer to show current state
     595                        ob_flush();
     596                        flush();
     597                        usleep(50000);
     598                }
     599               
     600                // Clean up after using the output buffer
     601                ob_end_flush();
     602               
     603                // If there are no more posts end the list tags
     604                if ( $this->next_url == '' ) {
     605                        echo '</ol>';           
     606                        do_action('import_done', 'typepad');           
     607                        echo '<h3>'.sprintf(__('All done. <a href="%s">Have fun!</a>'), get_option('home')).'</h3></div>';
     608                }
     609        }
     610       
     611        function save_post(&$post, &$comments, &$pings) {
     612                $post = get_object_vars($post);
     613                $post = add_magic_quotes($post);
     614                $post = (object) $post;
     615               
     616                if ( $post_id = post_exists($post->post_title, '', $post->post_date) ) {
     617                        echo '<li>';
     618                        printf(__('Post <em>%s</em> already exists.'), stripslashes($post->post_title));
     619                } else {
     620                        echo '<li>';
     621                        printf(__('Importing post <em>%s</em>...'), stripslashes($post->post_title));
     622                       
     623                        $post->post_author = $this->check_author($post->post_author); //just so that if a post already exists, new users are not created by checkauthor
     624                        $post_id = wp_insert_post($post);
     625                        if ( is_wp_error( $post_id ) )
     626                                return $post_id;
     627               
     628                        // Add categories.
     629                        if ( 0 != count($post->categories) ) {
     630                                wp_create_categories($post->categories, $post_id);
     631                        }
     632                       
     633                        // Add tags or keywords
     634                        if ( 1 < strlen($post->post_keywords) ) {
     635                                // Keywords exist.
     636                                printf(__('<br />Adding tags <i>%s</i>...'), stripslashes($post->post_keywords));
     637                                wp_add_post_tags($post_id, $post->post_keywords);
     638                        }
     639                       
     640                        $num_comments = 0;
     641                        foreach ( $comments as $comment ) {
     642                                $comment = get_object_vars($comment);
     643                                $comment = add_magic_quotes($comment);
     644
     645                                if ( !comment_exists($comment['comment_author'], $comment['comment_date'])) {
     646                                        $comment['comment_post_ID'] = $post_id;
     647                                        $comment = wp_filter_comment($comment);
     648                                        wp_insert_comment($comment);
     649                                        $num_comments++;
     650                                }
     651                        }
     652
     653                        if ( $num_comments )
     654                                printf(' '.__ngettext('(%s comment)', '(%s comments)', $num_comments), $num_comments);
     655                       
     656                        $num_pings = 0;
     657                        foreach ( $pings as $ping ) {
     658                                $ping = get_object_vars($ping);
     659                                $ping = add_magic_quotes($ping);
     660
     661                                if ( !comment_exists($ping['comment_author'], $ping['comment_date'])) {
     662                                        $ping['comment_content'] = "<strong>{$ping['comment_author']}</strong>";
     663                                        $ping['comment_post_ID'] = $post_id;
     664                                        $ping = wp_filter_comment($ping);
     665                                        wp_insert_comment($ping);
     666                                        $num_pings++;
     667                                }
     668                        }
     669
     670                        if ( $num_pings )
     671                                printf(' '.__ngettext('(%s ping)', '(%s pings)', $num_pings), $num_pings);
     672                }
     673               
     674                echo '</li>';
     675        }
     676       
     677        function check_author($author) {
     678                global $wpdb;
     679               
     680                $user_id = username_exists($author);
     681               
     682                // If the username does not exist
     683                if ( !$user_id ) {
     684                        $pass = wp_generate_password();
     685                        $user_id = wp_create_user($author, $pass);
     686                }
     687               
     688                return $user_id;
     689        }
     690       
     691        function error() {
     692?>
     693                <div class="narrow">
     694                        <h3><?php _e('Import Failed'); ?></h3>
     695                        <p><?php _e('There was an error starting the import process. Please go back and verify that the URL, username, and password were entered correctly.'); ?></p>
     696                        <p><a href="<?php echo add_query_arg('step', 0); ?>"><?php _e('Restart the Import Process &raquo;')?></a></p>
     697                </div>
     698<?php
     699        }
     700       
     701        function import() {
     702                $this->header();
     703               
     704                // Add the username and password as a global
     705                $this->username = $_POST['mtuser'];
     706                $this->password = $_POST['mtpass'];
     707               
     708                // Use output buffering so the progress bar appears immediately
     709                if (ob_get_level() == 0) {
     710                    ob_start();
     711                }
     712               
     713                // Pad the page with some data so output buffering works across browsers
     714                echo str_pad('',4096);
     715               
     716?>
     717<h3><?php _e('Import in Progress, Results Will Appear Momentarily'); ?></h3>
     718
     719<p><?php _e('While the importer is running do not navigate away from this page.'); ?></p>
     720
     721<div class="progress_bar" style="float:left; width: 500px; height; 20px; padding: 1px; border: 1px solid #dadada;">
     722        <div class="progress_display" style="width: 0px; background: #ccc">&nbsp;</div>
     723</div>
     724<div class="progress_percent" style="padding: 2px;">&nbsp;<img src="<?php echo get_option('home'); ?>/wp-admin/images/loading.gif" alt="Loading" style="margin-bottom: -3px;" />&nbsp;<span class="percent">0</span>%</div>
     725<?php
     726               
     727                // Clear the output buffer
     728                ob_flush();
     729                flush();
     730                ob_end_flush();
     731               
     732                // While we have more posts
     733                do {
     734               
     735                        $result = $this->get_entries();
     736               
     737                        if ( $result != 'error' )               
     738                                $result = $this->process_posts();
     739               
     740                        if ( is_wp_error( $result ) )
     741                                echo $result->get_error_message();
     742                       
     743                        // Free memory for next round of post
     744                        unset($this->posts);
     745                        $this->posts = array();
     746                               
     747                } while ( $this->next_url != '' );
     748               
     749                $this->footer();
     750        }
     751       
     752        function dispatch() {
     753                if (empty ($_GET['step']))
     754                        $step = 0;
     755                else
     756                        $step = (int) $_GET['step'];
     757
     758                switch ($step) {
     759                        case 0 :
     760                                $this->greet();
     761                                break;
     762                        case 1 :
     763                                check_admin_referer('import-typepad');
     764                                $this->import();
     765                                break;
     766                }
     767        }
     768
     769        function Typepad_Import() {
     770                // Nothing.
     771        }
     772}
     773
     774$typepad_import = new Typepad_Import();
     775
     776register_importer('typepad', __('TypePad - Web'), __('Import posts and comments from a TypePad blog with only your login credentials.'), array ($typepad_import, 'dispatch'));
     777?>
     778 No newline at end of file