WordPress.org

Make WordPress Core

Ticket #7543: atompub-importer.diff

File atompub-importer.diff, 49.9 KB (added by cavemonkey50, 6 years ago)

Current AtomPub importer work as of 8/18/08.

  • wp-admin/import/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'), __('Import posts, comments, and categories from a TypePad blog.'), array ($typepad_import, 'dispatch')); 
     777?> 
     778 No newline at end of file 
  • wp-admin/import/mt-atom.php

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

     
    2424 
    2525        function header() { 
    2626                echo '<div class="wrap">'; 
    27                 echo '<h2>'.__('Import Movable Type or TypePad').'</h2>'; 
     27                echo '<h2>'.__('Import Movable Type Old').'</h2>'; 
    2828        } 
    2929 
    3030        function footer() { 
     
    3535                $this->header(); 
    3636?> 
    3737<div class="narrow"> 
    38 <p><?php _e('Howdy! We&#8217;re about to begin importing all of your Movable Type or Typepad entries into WordPress. To begin, either choose a file to upload and click "Upload file and import," or use FTP to upload your MT export file as <code>mt-export.txt</code> in your <code>/wp-content/</code> directory and then click "Import mt-export.txt"'); ?></p> 
     38<p><?php _e('Howdy! We&#8217;re about to begin importing all of your Movable Type entries into WordPress. To begin, either choose a file to upload and click "Upload file and import," or use FTP to upload your MT export file as <code>mt-export.txt</code> in your <code>/wp-content/</code> directory and then click "Import mt-export.txt"'); ?></p> 
    3939 
    4040<?php wp_import_upload_form( add_query_arg('step', 1) ); ?> 
    4141<form method="post" action="<?php echo add_query_arg('step', 1); ?>" class="import-upload-form"> 
     
    478478 
    479479$mt_import = new MT_Import(); 
    480480 
    481 register_importer('mt', __('Movable Type and TypePad'), __('Import posts and comments from a Movable Type or Typepad blog.'), array ($mt_import, 'dispatch')); 
     481register_importer('mt', __('Movable Type Old'), __('Import posts and comments from a Movable Type blog version 4.12 or older.'), array ($mt_import, 'dispatch')); 
    482482?>