Make WordPress Core


Ignore:
Timestamp:
02/17/2009 07:58:03 PM (17 years ago)
Author:
ryan
Message:

LJ importer updates. Props beaulebens. see #8999

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-admin/import/livejournal.php

    r10538 r10586  
    1616 * Imports your LiveJournal contents into WordPress using the LJ API
    1717 *
    18  * @since 2.7.1
     18 * @since 2.8
    1919 */
    2020class LJ_API_Import {
     
    191191                <?php else : ?>
    192192                        <input type="hidden" name="step" value="1" />
     193                        <input type="hidden" name="login" value="true" />
    193194                        <p><?php _e( 'Howdy! This importer allows you to connect directly to LiveJournal and download all your entries and comments' ) ?></p>
    194195                        <p><?php _e( 'Enter your LiveJournal username and password below so we can connect to your account:' ) ?></p>
     
    237238        }
    238239       
    239         function import_posts() {
     240        function download_post_meta() {
    240241                $total           = (int) get_option( 'ljapi_total' );
    241242                $count           = (int) get_option( 'ljapi_count' );
     
    251252                        $lastsync = date( 'Y-m-d H:i:s', strtotime( get_option( 'ljapi_lastsync' ) ) );
    252253                        $synclist = $this->lj_ixr( 'syncitems', array( 'ver' => 1, 'lastsync' => $lastsync ) );
    253                        
     254                        if ( is_wp_error( $synclist ) )
     255                                return $synclist;
     256                               
    254257                        // Keep track of if we've downloaded everything
    255258                        $total = $synclist['total'];
     
    259262                                if ( substr( $event['item'], 0, 2 ) == 'L-' ) {
    260263                                        $sync_item_times[ str_replace( 'L-', '', $event['item'] ) ] = $event['time'];
    261                                         if ( $event['time'] > $lastsync )
     264                                        if ( $event['time'] > $lastsync ) {
    262265                                                $lastsync = $event['time'];
     266                                                update_option( 'ljapi_lastsync', $lastsync );
     267                                        }
    263268                                }
    264269                        }
    265270                } while ( $total > $count );
    266271                // endwhile - all post meta is cached locally
    267                
     272                unset( $synclist );
    268273                update_option( 'ljapi_sync_item_times', $sync_item_times );
    269274                update_option( 'ljapi_total', $total );
    270275                update_option( 'ljapi_count', $count );
    271                 update_option( 'ljapi_lastsync', $lastsync );
    272276
    273277                echo '<p>' . __( 'Post metadata has been downloaded, proceeding with posts...' ) . '</p>';
    274                
    275                 echo '<ol>';
    276                
    277                 $imported_count = (int) get_option( 'ljapi_imported_count' );
    278                 $lastsync = get_option( 'ljapi_lastsync_posts' );
     278        }
     279       
     280        function download_post_bodies() {
     281                $imported_count  = (int) get_option( 'ljapi_imported_count' );
     282                $sync_item_times = get_option( 'ljapi_sync_item_times' );
     283                $lastsync        = get_option( 'ljapi_lastsync_posts' );
    279284                if ( !$lastsync )
    280285                        update_option( 'ljapi_lastsync_posts', date( 'Y-m-d H:i:s', 0 ) );
    281                
     286
     287                $count = 0;
     288                echo '<ol>';           
    282289                do {
    283290                        $lastsync = date( 'Y-m-d H:i:s', strtotime( get_option( 'ljapi_lastsync_posts' ) ) );
     
    290297                        if ( is_wp_error( $itemlist ) )
    291298                                return $itemlist;
    292                                
     299                       
    293300                        if ( $num = count( $itemlist['events'] ) ) {
    294                                 foreach ( $itemlist['events'] as $event ) {
     301                                for ( $e = 0; $e < count( $itemlist['events'] ); $e++ ) {
     302                                        $event = $itemlist['events'][$e];
    295303                                        $imported_count++;
    296                                         $this->import_post( $event );
     304                                        $inserted = $this->import_post( $event );
     305                                        if ( is_wp_error( $inserted ) )
     306                                                return $inserted;
    297307                                        if ( $sync_item_times[ $event['itemid'] ] > $lastsync )
    298308                                                $lastsync = $sync_item_times[ $event['itemid'] ];
     309                                        wp_cache_flush();
    299310                                }
    300311                                update_option( 'ljapi_lastsync_posts',  $lastsync );
     
    302313                                update_option( 'ljapi_last_sync_count', $num );
    303314                        }
    304                 } while ( $num > 0 );
     315                        $count++;
     316                } while ( $num > 0 && $count < 3 ); // Doing up to 3 requests at a time to avoid memory problems
     317               
     318                // Used so that step1 knows when to stop posting back on itself
     319                update_option( 'ljapi_last_sync_count', $num );
     320               
     321                // Counter just used to show progress to user
     322                update_option( 'ljapi_post_batch', ( (int) get_option( 'ljapi_post_batch' ) + 1 ) );
    305323
    306324                echo '</ol>';
     
    357375                        printf( __( 'Post <strong>%s</strong> already exists.' ), stripslashes( $post_title ) );
    358376                } else {
    359                         printf( __( 'Importing post <strong>%s</strong>...' ), stripslashes( $post_title ) );
     377                        printf( __( 'Imported post <strong>%s</strong>...' ), stripslashes( $post_title ) );
    360378                        $postdata = compact( 'post_author', 'post_date', 'post_content', 'post_title', 'post_status', 'post_password', 'tags_input', 'comment_status' );
    361                         $post_id = wp_insert_post( $postdata );
    362                         if ( is_wp_error( $post_id ) )
     379                        $post_id = wp_insert_post( $postdata, true );
     380                        if ( is_wp_error( $post_id ) ) {
     381                                if ( 'empty_content' == $post_id->get_error_code() )
     382                                        return; // Silent skip on "empty" posts
    363383                                return $post_id;
     384                        }
    364385                        if ( !$post_id ) {
    365                                 _e( "Couldn't get post ID" );
     386                                _e( "Couldn't get post ID (creating post failed!)" );
    366387                                echo '</li>';
    367                                 break;
    368                         }
    369                         $postdata['post_ID']   = $post_id;
    370                         $postdata['lj_itemid'] = $post['itemid'];
     388                                return new WP_Error( 'insert_post_failed', __( 'Failed to create post.' ) );
     389                        }
    371390                       
    372391                        // Handle all the metadata for this post
     
    408427       
    409428        // Set up a session (authenticate) with LJ
    410         function getsession() {
     429        function get_session() {
    411430                // Get a session via XMLRPC
    412431                $cookie = $this->lj_ixr( 'sessiongenerate', array( 'ver' => 1, 'expiration' => 'short' ) );
     432                if ( is_wp_error( $cookie ) )
     433                        return new WP_Error( 'cookie', __( 'Could not get a cookie from LiveJournal. Please try again soon.' ) );
    413434                return new WP_Http_Cookie( array( 'name' => 'ljsession', 'value' => $cookie['ljsession'] ) );
    414435        }
     
    416437        // Loops through and gets comment meta from LJ in batches
    417438        function download_comment_meta() {
    418                 $cookie = $this->getsession();
     439                $cookie = $this->get_session();
     440                if ( is_wp_error( $cookie ) )
     441                        return $cookie;
    419442               
    420443                // Load previous state (if any)
     
    464487                update_option( 'ljapi_highest_id', $highest_id );
    465488               
    466                 echo '<p>' . __( ' Comment metadata downloaded successfully, proceeding with posts...' ) . '</p>';
     489                echo '<p>' . __( ' Comment metadata downloaded successfully, proceeding with comment bodies...' ) . '</p>';
    467490               
    468491                return true;
     
    473496        function download_comment_bodies() {
    474497                global $wpdb;
    475                 $cookie = $this->getsession();
     498                $cookie = $this->get_session();
     499                if ( is_wp_error( $cookie ) )
     500                        return $cookie;
    476501               
    477502                // Load previous state (if any)
     
    604629        function get_wp_post_ID( $post ) {
    605630                global $wpdb;
     631               
    606632                if ( empty( $this->postmap[$post] ) )
    607633                        $this->postmap[$post] = (int) $wpdb->get_var( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = 'lj_itemid' AND meta_value = %d", $post ) );
     634               
    608635                return $this->postmap[$post];
    609636        }
     
    627654                                                        'auth_response' => md5( $challenge['challenge'] . md5( $this->password ) ) );
    628655                } else {
    629                         return new WP_Error( 'IXR', __( 'LiveJournal does not appear to be responding right now. Please try again later.' ) );
     656                        return new WP_Error( 'IXR', __( 'LiveJournal is not responding to authentication requests. Please wait a while and then try again.' ) );
    630657                }
    631658               
     
    637664                        return $this->ixr->getResponse();
    638665                } else {
    639                         return new WP_Error( 'IXR', __( 'XML-RPC Request Failed - ' ) . $this->ixr->getErrorCode() . ': ' . $this->ixr->getErrorMessage() );
     666                        return new WP_Error( 'IXR', __( 'XML-RPC Request Failed -- ' ) . $this->ixr->getErrorCode() . ': ' . $this->ixr->getErrorMessage() );
    640667                }
    641668        }
     
    657684                                break;
    658685                        case 1 :
    659                                 $this->ixr = new IXR_Client( $this->ixr_url );
    660                                 // Intentional no break
    661686                        case 2 :
    662687                        case 3 :
    663688                                check_admin_referer( 'lj-api-import' );
    664689                                $result = $this->{ 'step' . $step }();
    665                                 if ( is_wp_error( $result ) )
    666                                         echo $result->get_error_message();
     690                                if ( is_wp_error( $result ) ) {
     691                                        $this->throw_error( $result, $step );
     692                                }
    667693                                break;
    668694                }
     
    671697        }
    672698
    673         // Check form inputs and start importing posts
    674         function step1() {
     699        // Technically the first half of step 1, this is separated to allow for AJAX
     700        // calls. Sets up some variables and options and confirms authentication.
     701        function setup() {
     702                global $verified;
    675703                // Get details from form or from DB
    676704                if ( !empty( $_POST['lj_username'] ) && !empty( $_POST['lj_password'] ) ) {
     
    699727                        <p><a href="<?php echo $_SERVER['PHP_SELF'] . '?import=livejournal&amp;step=-1&amp;_wpnonce=' . wp_create_nonce( 'lj-api-import' ) . '&amp;_wp_http_referer=' . attribute_escape( str_replace( '&step=1', '', $_SERVER['REQUEST_URI'] ) ) ?>"><?php _e( 'Start again' ) ?></a></p>
    700728                        <?php
    701                         return;
    702                 }
    703                 $login = $this->lj_ixr( 'login' );
    704                 if ( is_wp_error( $login ) ) {
     729                        return false;
     730                }
     731                $verified = $this->lj_ixr( 'login' );
     732                if ( is_wp_error( $verified ) ) {
    705733                        if ( 100 == $this->ixr->getErrorCode() || 101 == $this->ixr->getErrorCode() ) {
    706734                                delete_option( 'ljapi_username' );
    707735                                delete_option( 'ljapi_password' );
     736                                delete_option( 'ljapi_protected_password' );
    708737                                ?>
    709738                                <p><?php _e( 'Logging in to LiveJournal failed. Check your username and password and try again.' ) ?></p>
    710739                                <p><a href="<?php echo $_SERVER['PHP_SELF'] . '?import=livejournal&amp;step=-1&amp;_wpnonce=' . wp_create_nonce( 'lj-api-import' ) . '&amp;_wp_http_referer=' . attribute_escape( str_replace( '&step=1', '', $_SERVER['REQUEST_URI'] ) ) ?>"><?php _e( 'Start again' ) ?></a></p>
    711740                                <?php
    712                                 return;
     741                                return false;
    713742                        } else {
    714                                 return $login;
    715                         }
     743                                return $verified;
     744                        }
     745                } else {
     746                        update_option( 'ljapi_verified', 'yes' );
    716747                }
    717748               
     
    721752                update_option( 'ljapi_comment_batch', 0 );
    722753               
     754                return true;
     755        }
     756
     757        // Check form inputs and start importing posts
     758        function step1() {
     759                global $verified;
     760                set_time_limit( 0 );
     761                update_option( 'ljapi_step', 1 );
     762                if ( !$this->ixr ) $this->ixr = new IXR_Client( $this->ixr_url, false, 80, 30 );
     763                if ( empty( $_POST['login'] ) ) {
     764                        // We're looping -- load some details from DB
     765                        $this->username = get_option( 'ljapi_username' );
     766                        $this->password = get_option( 'ljapi_password' );
     767                        $this->protected_password = get_option( 'ljapi_protected_password' );
     768                } else {
     769                        // First run (non-AJAX)
     770                        $setup = $this->setup();
     771                        if ( !$setup ) {
     772                                return false;
     773                        } else if ( is_wp_error( $setup ) ) {
     774                                $this->throw_error( $setup, 1 );
     775                                return false;
     776                        }
     777                }
     778               
     779                echo '<div id="ljapi-status">';
    723780                echo '<h3>' . __( 'Importing Posts' ) . '</h3>';
    724                 echo '<p>' . __( "We're downloading and importing all your LiveJournal posts..." ) . '</p>';
     781                echo '<p>' . __( "We're downloading and importing your LiveJournal posts..." ) . '</p>';
     782                if ( get_option( 'ljapi_post_batch' ) && count( get_option( 'ljapi_sync_item_times' ) ) ) {
     783                        $batch = count( get_option( 'ljapi_sync_item_times' ) );
     784                        $batch = $count > 300 ? ceil( $batch / 300 ) : 1;
     785                        echo '<p><strong>' . sprintf( __( 'Imported post batch %d of <strong>approximately</strong> %d' ), ( get_option( 'ljapi_post_batch' ) + 1 ), $batch ) . '</strong></p>';
     786                }
    725787                ob_flush(); flush();
    726788               
    727                 // Now do the grunt work
    728                 set_time_limit( 0 );
    729                 $result = $this->import_posts();
     789                if ( !get_option( 'ljapi_lastsync' ) || '1900-01-01 00:00:00' == get_option( 'ljapi_lastsync' ) ) {
     790                        // We haven't downloaded meta yet, so do that first
     791                        $result = $this->download_post_meta();
     792                        if ( is_wp_error( $result ) ) {
     793                                $this->throw_error( $result, 1 );
     794                                return false;
     795                        }
     796                }
     797
     798                // Download a batch of actual posts
     799                $result = $this->download_post_bodies();
    730800                if ( is_wp_error( $result ) ) {
    731801                        if ( 406 == $this->ixr->getErrorCode() ) {
     
    734804                                <p><strong><?php _e( "We've saved where you were up to though, so if you come back to this importer in about 30 minutes, you should be able to continue from where you were." ) ?></strong></p>
    735805                                <?php
    736                                 return;
     806                                echo $this->next_step( 1, __( 'Try Again' ) );
     807                                return false;
    737808                        } else {
    738                                 return $result;
    739                         }
    740                 }
    741                
    742                 echo '<p>' . __( "Your posts have all been imported, but wait - there's more! Now we need to download &amp; import your comments." ) . '</p>';
    743                 echo $this->next_step( 2, __( 'Download my comments &raquo;' ) );
    744                 $this->auto_submit();
     809                                $this->throw_error( $result, 1 );
     810                                return false;
     811                        }
     812                }
     813
     814                if ( get_option( 'ljapi_last_sync_count' ) > 0 ) {
     815                ?>
     816                        <form action="admin.php?import=livejournal" method="post" id="ljapi-auto-repost">
     817                        <?php wp_nonce_field( 'lj-api-import' ) ?>
     818                        <input type="hidden" name="step" id="step" value="1" />
     819                        <p><input type="submit" class="button-primary" value="<?php echo attribute_escape( __( 'Import the next batch &raquo;' ) ) ?>" /> <span id="auto-message"></span></p>
     820                        </form>
     821                        <?php $this->auto_ajax( 'ljapi-auto-repost', 'auto-message', 0 ); ?>
     822                <?php
     823                } else {
     824                        echo '<p>' . __( "Your posts have all been imported, but wait - there's more! Now we need to download &amp; import your comments." ) . '</p>';
     825                        echo $this->next_step( 2, __( 'Download my comments &raquo;' ) );
     826                        $this->auto_submit();
     827                }
     828                echo '</div>';
    745829        }
    746830       
     
    751835                $this->username = get_option( 'ljapi_username' );
    752836                $this->password = get_option( 'ljapi_password' );
    753                 $this->ixr = new IXR_Client( $this->ixr_url );
     837                $this->ixr = new IXR_Client( $this->ixr_url, false, 80, 30 );
    754838               
    755839                echo '<div id="ljapi-status">';
     
    761845                        // We haven't downloaded meta yet, so do that first
    762846                        $result = $this->download_comment_meta();
    763                         if ( is_wp_error( $result ) )
    764                                 return $result;
     847                        if ( is_wp_error( $result ) ) {
     848                                $this->throw_error( $result, 2 );
     849                                return false;
     850                        }
    765851                }
    766852
    767853                // Download a batch of actual comments
    768854                $result = $this->download_comment_bodies();
    769                 if ( is_wp_error( $result ) )
    770                         return $result;
     855                if ( is_wp_error( $result ) ) {
     856                        $this->throw_error( $result, 2 );
     857                        return false;
     858                }
    771859
    772860                $maxid      = get_option( 'ljapi_maxid' ) ? (int) get_option( 'ljapi_maxid' ) : 1;
    773861                $highest_id = (int) get_option( 'ljapi_highest_comment_id' );
    774862                if ( $maxid > $highest_id ) {
     863                        $batch = $maxid > 5000 ? ceil( $maxid / 5000 ) : 1;
    775864                ?>
    776865                        <form action="admin.php?import=livejournal" method="post" id="ljapi-auto-repost">
    777                         <p><strong><?php printf( __( 'Imported comment batch %d of <strong>approximately</strong> %d' ), get_option( 'ljapi_comment_batch' ), ( $maxid / 5000 ) ) ?></strong></p>
     866                        <p><strong><?php printf( __( 'Imported comment batch %d of <strong>approximately</strong> %d' ), get_option( 'ljapi_comment_batch' ), $batch ) ?></strong></p>
    778867                        <?php wp_nonce_field( 'lj-api-import' ) ?>
    779868                        <input type="hidden" name="step" id="step" value="2" />
     
    835924                do_action( 'import_done', 'livejournal' );
    836925                if ( $imported_comments > 1 )
    837                         echo '<p>' . sprintf( __( "Successfully re-threaded %d comments." ), number_format( $imported_comments ) ) . '</p>';
     926                        echo '<p>' . sprintf( __( "Successfully re-threaded %s comments." ), number_format( $imported_comments ) ) . '</p>';
    838927                echo '<h3>';
    839928                printf( __( 'All done. <a href="%s">Have fun!</a>' ), get_option( 'home' ) );
    840929                echo '</h3>';
    841930                echo '</div>';
     931        }
     932       
     933        // Output an error message with a button to try again.
     934        function throw_error( $error, $step ) {
     935                echo '<p><strong>' . $error->get_error_message() . '</strong></p>';
     936                echo $this->next_step( $step, __( 'Try Again' ) );
    842937        }
    843938       
     
    9211016                delete_option( 'ljapi_password' );
    9221017                delete_option( 'ljapi_protected_password' );
     1018                delete_option( 'ljapi_verified' );
    9231019                delete_option( 'ljapi_total' );
    9241020                delete_option( 'ljapi_count' );
     
    9271023                delete_option( 'ljapi_sync_item_times' );
    9281024                delete_option( 'ljapi_lastsync_posts' );
     1025                delete_option( 'ljapi_post_batch' );
    9291026                delete_option( 'ljapi_imported_count' );
    9301027                delete_option( 'ljapi_maxid' );
Note: See TracChangeset for help on using the changeset viewer.