WordPress.org

Make WordPress Core

Ticket #7543: typepad.diff

File typepad.diff, 23.2 KB (added by cavemonkey50, 6 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