• Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • Examples
  • File List

system/plugins/wpimport/wpimport.plugin.php

00001 <?php
00002 
00003 namespace Habari;
00004 
00005 if ( !defined( 'HABARI_PATH' ) ) { die( 'No direct access' ); }
00006 
00007   // define IMPORT_BATCH in your config.php to limit each batch of DB results
00008   if ( !defined('IMPORT_BATCH') ) {
00009     define('IMPORT_BATCH', 100);
00010   }
00011 
00022   class WPImport extends Plugin implements Importer {
00023 
00024     private $supported_importers = array();
00025 
00026     private $default_values = array(
00027       'db_name' => '',
00028       'db_host' => 'localhost',
00029       'db_user' => '',
00030       'db_pass' => '',
00031       'db_prefix' => 'wp_',
00032       'category_import' => true,
00033       'import_index' => 0,
00034       'error' => '',
00035     );
00036 
00041     public function action_init ( ) {
00042 
00043       $this->supported_importers[] = _t('WordPress Database');
00044 
00045     }
00046 
00054     public function filter_import_names ( $import_names ) {
00055 
00056       return array_merge( $import_names, $this->supported_importers );
00057 
00058     }
00059 
00070     public function filter_import_stage ( $stage_output, $import_name, $stage, $step ) {
00071 
00072       // only act on this filter if the import_name is one we handle
00073       if ( !in_array( $import_name, $this->supported_importers ) ) {
00074         // it's a filter, always return the output another plugin might have generated
00075         return $stage_output;
00076       }
00077 
00078       // the values we'll hand to each stage for processing
00079       $inputs = array();
00080 
00081       // validate input and figure out which stage we're at
00082       switch ( $stage ) {
00083 
00084         case 1:
00085 
00086           if ( isset( $_POST['wpimport'] ) ) {
00087 
00088             $inputs = $_POST->filter_keys( array( 'db_name', 'db_user', 'db_host', 'db_pass', 'db_prefix', 'category_import', 'import_index' ) );
00089             $inputs = $inputs->getArrayCopy();
00090 
00091             // try to connect to the db with the given values
00092             if ( $this->wp_connect( $inputs['db_host'], $inputs['db_name'], $inputs['db_user'], $inputs['db_pass'] ) ) {
00093 
00094               // we've got good connection info, bump to stage 2
00095               $stage = 2;
00096 
00097             }
00098             else {
00099 
00100               // add a warning to the stack
00101               $inputs['error'] = _t('Could not connect to the WordPress database using the values supplied. Please correct them and try again.');
00102 
00103             }
00104 
00105           }
00106 
00107           break;
00108 
00109       }
00110 
00111 
00112       // now dispatch the right stage
00113       switch ( $stage ) {
00114 
00115         case 1:
00116         default:
00117           $output = $this->stage1( $inputs, $import_name );
00118           break;
00119 
00120         case 2:
00121           $output = $this->stage2( $inputs );
00122           break;
00123 
00124       }
00125 
00126       // return the output for the importer to display
00127       return $output;
00128 
00129     }
00130 
00140     private function stage1 ( $inputs, $import_name ) {
00141 
00142       $inputs = array_merge( $this->default_values, $inputs );
00143 
00144       // if there is a error, display it
00145       if ( $inputs['error'] != '' ) {
00146         $error = '<p class="error">' . $inputs['error'] . '</p>';
00147       }
00148       else {
00149         // blank it out just so we can use the value in output
00150         $error = '';
00151       }
00152 
00153       $output = '<p>' . _t( 'Habari will attempt to import from a WordPress database.') . '</p>';
00154       $output .= $error;
00155 
00156       // get the FormUI form
00157       $form = $this->get_form( $inputs, $import_name );
00158 
00159       // append the output of the form
00160       $output .= $form->get();
00161 
00162 //      $output .= '<div class="item clear">';
00163 //      $output .=  '<span class="pct25"><label for="db_name">' . _t( 'Database Name' ) . '</label></span><span class="pct40"><input type="text" name="db_name" id="db_name" value="' . $inputs['db_name'] . '"></span>';
00164 //      $output .= '</div>';
00165 
00166 //      $output .= '<div class="item clear">';
00167 //      $output .=  '<span class="pct25"><label for="db_host">' . _t( 'Database Host' ) . '</label></span><span class="pct40"><input type="text" name="db_host" id="db_host" value="' . $inputs['db_host'] . '"></span>';
00168 //      $output .= '</div>';
00169 
00170 //      $output .= '<div class="item clear">';
00171 //      $output .=  '<span class="pct25"><label for="db_user">' . _t( 'Database User' ) . '</label></span><span class="pct40"><input type="text" name="db_user" id="db_user" value="' . $inputs['db_user'] . '"></span>';
00172 //      $output .= '</div>';
00173 
00174 //      $output .= '<div class="item clear">';
00175 //      $output .=  '<span class="pct25"><label for="db_pass">' . _t( 'Database Password' ) . '</label></span><span class="pct40"><input type="text" name="db_pass" id="db_pass" value="' . $inputs['db_pass'] . '"></span>';
00176 //      $output .= '</div>';
00177 
00178 //      $output .= '<div class="item clear">';
00179 //      $output .=  '<span class="pct25"><label for="db_prefix">' . _t( 'Table Prefix' ) . '</label></span><span class="pct40"><input type="text" name="db_prefix" id="db_prefix" value="' . $inputs['db_prefix'] . '"></span>';
00180 //      $output .= '</div>';
00181 
00182 //      $output .= '<div class="item clear">';
00183 //      $output .=  '<span class="pct25"><label for="category_import">' . _t( 'Import Categories as Tags' ) . '</label></span><span class="pct40"><input type="checkbox" name="category_import" id="category_import" value="true" ' . ( ( $inputs['category_import'] == true ) ? 'checked="checked"' : '' ) . '></span>';
00184 //      $output .= '</div>';
00185 
00186 //      $output .= '<div class="item clear transparent">';
00187 //      $output .=  '<input type="submit" class="button" name="wpimport" value="' . _t( 'Import' ) . '">';
00188 //      $output .= '</div>';
00189 
00190       return $output;
00191 
00192     }
00193 
00200     private function stage2 ( $inputs ) {
00201 
00202       // make sure we have all our default values
00203       $inputs = array_merge( $this->default_values, $inputs );
00204 
00205       // the first thing we import are users, so get that URL to kick off the ajax process
00206       $ajax_url = URL::get( 'auth_ajax', array( 'context' => 'wp_import_users' ) );
00207 
00208       // the variables we'll hand to the ajax call are all the input values
00209       $vars = $inputs;
00210 
00211       EventLog::log( _t('Starting import from "%s"', array( $inputs['db_name'] ) ) );
00212 
00213       $output = '<p>' . _t('Import in Progress') . '</p>';
00214       $output .= '<div id="import_progress">' . _t( 'Starting Import&hellip;' ) . '</div>';
00215       $output .= $this->get_ajax( $ajax_url, $vars );
00216 
00217       return $output;
00218 
00219     }
00220 
00228     private function get_ajax ( $url, $vars = array() ) {
00229 
00230       // generate the vars we'll use
00231       $ajax_vars = array();
00232       foreach ( $vars as $k => $v ) {
00233         $ajax_vars[] = $k . ': "' . $v . '"';
00234       }
00235       $ajax_vars = implode( ',', $ajax_vars );
00236 
00237       $output = <<<WP_IMPORT_AJAX
00238         <script type="text/javascript">
00239           $(document).ready( function() {
00240             $('#import_progress').load(
00241               "{$url}",
00242               {
00243                 {$ajax_vars}
00244               }
00245             );
00246           } );
00247         </script>
00248 WP_IMPORT_AJAX;
00249 
00250       return $output;
00251 
00252     }
00253 
00261     private function get_form ( $inputs, $import_name ) {
00262       // this isn't used right now because we can't use formui in an importer, there's already a form
00263       $form = new FormUI('wp_importer');
00264 
00265       $form->append( FormControlStatic::create( '<p>' . _t( 'Habari will attempt to import from a WordPress database.') . '</p>' ) );
00266 
00267       $form->append( FormControlLabel::wrap( _t( 'Database Name'),
00268         FormControlText::create( 'db_name' )->set_value( $inputs['db_name'] )
00269       ));
00270 
00271       $form->append( FormControlLabel::wrap( _t( 'Database Host'),
00272         FormControlText::create( 'db_host' )->set_value( $inputs['db_host'] )
00273       ));
00274 
00275       $form->append( FormControlLabel::wrap( _t( 'Database User'),
00276         FormControlText::create( 'db_user' )->set_value( $inputs['db_user'] )
00277       ));
00278 
00279       $form->append( FormControlLabel::wrap( _t( 'Database Password'),
00280         FormControlText::create( 'db_pass' )->set_value( $inputs['db_pass'] )
00281       ));
00282 
00283       $form->append( FormControlLabel::wrap( _t( 'Table Prefix'),
00284         FormControlText::create( 'db_prefix' )->set_value( $inputs['db_prefix'] )
00285       ));
00286 
00287       $form->append( FormControlLabel::wrap( _t( 'Import Categories as Tags' ),
00288         FormControlCheckbox::create( 'category_import' )->set_value( $inputs['category_import'] )
00289       ));
00290 
00291       $form->append( FormControlData::create( 'stage' )->set_value( 1 ) );
00292 
00293       $form->append( FormControlHidden::create( 'importer' )->set_value( $import_name ) );
00294 
00295       $form->append( FormControlSubmit::create( 'wpimport' )->set_caption( _t( 'Import' ) )->add_class( 'button' ) );
00296 
00297       $form->set_wrap_each( '<div>%s</div>' );
00298 
00299       return $form;
00300 
00301     }
00302 
00313     private function wp_connect ( $db_host, $db_name, $db_user, $db_pass ) {
00314 
00315       // build the connection string, since we stupidly have to use it twice
00316       $connection_string = 'mysql:host=' . $db_host . ';dbname=' . $db_name;
00317 
00318       try {
00319         $wpdb = DatabaseConnection::ConnectionFactory( $connection_string );
00320         $wpdb->connect( $connection_string, $db_user, $db_pass );
00321 
00322         // @todo make sure preifx_* tables exist?
00323 
00324         return $wpdb;
00325       }
00326       catch ( \Exception $e ) {
00327         // just hide connection errors, it's enough that we errored out
00328         return false;
00329       }
00330 
00331     }
00332 
00338     public function action_auth_ajax_wp_import_users ( ) {
00339 
00340       // get the values post'd in
00341       $inputs = $_POST->filter_keys( array( 'db_name', 'db_host', 'db_user', 'db_pass', 'db_prefix', 'category_import', 'import_index' ) );
00342       $inputs = $inputs->getArrayCopy();
00343 
00344       // make sure we have all our default values
00345       $inputs = array_merge( $this->default_values, $inputs );
00346 
00347       // get the wpdb
00348       $wpdb = $this->wp_connect( $inputs['db_host'], $inputs['db_name'], $inputs['db_user'], $inputs['db_pass'] );
00349 
00350       // if we couldn't connect, error out
00351       if ( !$wpdb ) {
00352         EventLog::log( _t( 'Failed to import from "%s"', array( $inputs['db_name'] ) ) );
00353         Session::error( _t( 'Failed to import from "%s"', array( $inputs['db_name'] ) ) );
00354         echo '<p>' . _t( 'Failed to connect using the given database connection details.' ) . '</p>';
00355       }
00356 
00357       // we connected just fine, let's get moving!
00358 
00359       // begin a transaction. if we error out at any point, we want to roll back to before import began
00360       DB::begin_transaction();
00361 
00362       // fetch all the users from the wordpress database
00363       $wp_users = $wpdb->get_results( 'select id, user_login, user_pass, user_email, user_url, display_name from ' . $inputs['db_prefix'] . 'users' );
00364 
00365       echo '<p>' . _t( 'Importing Users&hellip;' ) . '</p>';
00366 
00367       foreach ( $wp_users as $wp_user ) {
00368 
00369         // see if a user with this username already exists
00370         $user = User::get_by_name( $wp_user->user_login );
00371 
00372         if ( $user !== false ) {
00373 
00374           // if the user exists, save their old ID into an info attribute
00375           $user->info->wp_id = intval( $wp_user->id );
00376 
00377           // and update
00378           $user->update();
00379 
00380           echo '<p>' . _t( 'Associated imported user %1$s with existing user %2$s', array( $wp_user->user_login, $user->username ) ) . '</p>';
00381 
00382           EventLog::log( _t( 'Associated imported user %1$s with existing user %2$s', array( $wp_user->user_login, $user->username ) ) );
00383 
00384         }
00385         else {
00386 
00387           // no user exists, we need to create one
00388           try {
00389 
00390             $u = new User();
00391             $u->username = $wp_user->user_login;
00392             $u->email = $wp_user->user_email;
00393 
00394             // set their password so the user will be able to login. they're auto-added to the 'authenticated' ACL group
00395             $u->password = Utils::crypt( $wp_user->user_pass );
00396 
00397             $u->info->wp_id = intval( $wp_user->id );
00398             $u->info->displayname = $wp_user->display_name;
00399 
00400             if ( $wp_user->user_url != '' ) {
00401               $u->info->url = $wp_user->user_url;
00402             }
00403 
00404             // and save it
00405             $u->insert();
00406 
00407             echo '<p>' . _t( 'Created new user %1$s. Their old ID was %2$d.', array( $u->username, $wp_user->id ) ) . '</p>';
00408 
00409             EventLog::log( _t( 'Created new user %1$s. Their old ID was %2$d.', array( $u->username, $wp_user->id ) ) );
00410 
00411           }
00412           catch ( \Exception $e ) {
00413 
00414             // no idea why we might error out, but catch it if we do
00415             EventLog::log( $e->getMessage, 'err' );
00416 
00417             echo '<p class="error">' . _t( 'There was an error importing user %s. See the EventLog for the error message. ', array( $wp_user->user_login ) ) . '</p>';
00418 
00419             echo '<p>' . _t( 'Rolling back changes&hellip;' ) . '</p>';
00420 
00421             // rollback all changes before we return so the import hasn't changed anything yet
00422             DB::rollback();
00423 
00424             // and return so they don't get AJAX to send them on to the next step
00425             return false;
00426 
00427           }
00428 
00429         }
00430 
00431       }
00432 
00433 
00434       // if we've finished without an error, commit the import
00435       DB::commit();
00436 
00437       // get the next ajax url
00438       $ajax_url = URL::get( 'auth_ajax', array( 'context' => 'wp_import_posts' ) );
00439 
00440       // and spit out ajax to send them to the next step - posts!
00441       echo $this->get_ajax( $ajax_url, $inputs );
00442 
00443     }
00444 
00450     public function action_auth_ajax_wp_import_posts ( ) {
00451 
00452       // get the values post'd in
00453       $inputs = $_POST->filter_keys( array( 'db_name', 'db_host', 'db_user', 'db_pass', 'db_prefix', 'category_import', 'import_index' ) );
00454       $inputs = $inputs->getArrayCopy();
00455 
00456       // make sure we have all our default values
00457       $inputs = array_merge( $this->default_values, $inputs );
00458 
00459       // get the wpdb
00460       $wpdb = $this->wp_connect( $inputs['db_host'], $inputs['db_name'], $inputs['db_user'], $inputs['db_pass'] );
00461 
00462       // if we couldn't connect, error out
00463       if ( !$wpdb ) {
00464         EventLog::log( _t( 'Failed to import from "%s"', array( $inputs['db_name'] ) ) );
00465         Session::error( _t( 'Failed to import from "%s"', array( $inputs['db_name'] ) ) );
00466         echo '<p>' . _t( 'Failed to connect using the given database connection details.' ) . '</p>';
00467       }
00468 
00469       // we connected just fine, let's get moving!
00470 
00471       // begin a transaction. if we error out at any point, we want to roll back to before import began
00472       DB::begin_transaction();
00473 
00474       // fetch the number of posts from the wordpress database so we can batch things up
00475       $num_posts = $wpdb->get_value( 'select count(id) from ' . $inputs['db_prefix'] . 'posts' );
00476 
00477       // figure out the LIMIT we're at
00478       $min = $inputs['import_index'] * IMPORT_BATCH;
00479       $max = min( $min + IMPORT_BATCH, $num_posts );    // for display only
00480 
00481 
00482       echo '<p>' . _t( 'Importing posts %1$d - %2$d of %3$d.', array( $min, $max, $num_posts ) ) . '</p>';
00483 
00484       // get all the imported users so we can link old post authors to new post authors
00485       $users = DB::get_results( 'select user_id, value from {userinfo} where name = :name', array( ':name' => 'wp_id' ) );
00486 
00487       // create an easy user map of old ID -> new ID
00488       $user_map = array();
00489       foreach ( $users as $info ) {
00490         $user_map[ $info->value ] = $info->user_id;
00491       }
00492 
00493       // get all the post IDs we've imported so far to make sure we don't duplicate any
00494       $post_map = DB::get_column( 'select value from {postinfo} where name = :name', array( ':name' => 'wp_id' ) );
00495 
00496 
00497 
00498       // now we're ready to start importing posts
00499       $posts = $wpdb->get_results( 'select id, post_author, post_date, post_content, post_title, post_status, comment_status, post_name, post_modified, guid, post_type from ' . $inputs['db_prefix'] . 'posts order by id asc limit ' . $min . ', ' . IMPORT_BATCH );
00500 
00501       foreach ( $posts as $post ) {
00502 
00503         // if this post is already in the list we've imported, skip it
00504         if ( in_array( $post->id, $post_map ) ) {
00505           continue;
00506         }
00507 
00508         // set up the big taxonomy sql query
00509         // if this turns out to be incredibly slow we should refactor it into a big join, but they're all keys so it seems zippy enough for me
00510         $taxonomy_query = 'select name, slug from ' . $inputs['db_prefix'] . 'terms where term_id in ( select term_id from ' . $inputs['db_prefix'] . 'term_taxonomy where taxonomy = :taxonomy and term_taxonomy_id in ( select term_taxonomy_id from ' . $inputs['db_prefix'] . 'term_relationships where object_id = :object_id ) )';
00511 
00512         // get all the textual tag names for this post
00513         $tags = $wpdb->get_results( $taxonomy_query, array( ':taxonomy' => 'post_tag', ':object_id' => $post->id ) );
00514 
00515         // should we import categories as tags too?
00516         if ( $inputs['category_import'] ) {
00517           // then do the same as above for the category taxonomy
00518           $categories = $wpdb->get_results( $taxonomy_query, array( ':taxonomy' => 'category', ':object_id' => $post->id ) );
00519         }
00520 
00521         // create the new post
00522         $p = new Post( array(
00523           'title' => MultiByte::convert_encoding( $post->post_title ),
00524           'content' => MultiByte::convert_encoding( $post->post_content ),
00525           'user_id' => $user_map[ $post->post_author ],
00526           'pubdate' => DateTime::create( $post->post_date ),
00527           'updated' => DateTime::create( $post->post_modified ),
00528           'slug' => MultiByte::convert_encoding( $post->post_name ),
00529         ) );
00530 
00531         // figure out the post type
00532         switch ( $post->post_type ) {
00533 
00534           case 'post':
00535             $p->content_type = Post::type( 'entry' );
00536             break;
00537 
00538           case 'page':
00539             $p->content_type = Post::type( 'page' );
00540             break;
00541 
00542           default:
00543             // we're not importing other types - continue 2 to break out of the switch and the loop and continue to the next post
00544             continue 2;
00545 
00546         }
00547 
00548         // figure out the post status
00549         switch ( $post->post_status ) {
00550 
00551           case 'publish':
00552             $p->status = Post::status( 'published' );
00553             break;
00554 
00555           case 'future':
00556             $p->status = Post::status( 'scheduled' );
00557             break;
00558 
00559           case 'pending':   // means pending-review, not pending as in scheduled
00560           case 'draft':
00561             $p->status = Post::status( 'draft' );
00562             break;
00563 
00564           default:
00565             // Post::status() returns false if it doesn't recognize the status type
00566             $status = Post::status( $post->post_status );   // store in a temp value because if you try and set ->status to an invalid value the Post class freaks
00567 
00568             if ( $status == false ) {
00569               // we're not importing statuses we don't recognize - continue 2 to break out of the switch and the loop and continue to the next post
00570               continue 2;
00571             }
00572             else {
00573               $p->status = $status;
00574             }
00575 
00576             break;
00577 
00578         }
00579 
00580         // if comments are closed, disable them on the new post
00581         if ( $post->comment_status == 'closed' ) {
00582           $p->info->comments_disabled = true;
00583         }
00584 
00585         // save the old post ID in info
00586         $p->info->wp_id = $post->id;
00587 
00588         // since we're not using it, save the old GUID too
00589         $p->info->wp_guid = $post->guid;
00590 
00591 
00592         // now that we've got all the pieces in place, save the post
00593         try {
00594           $p->insert();
00595 
00596           // now that the post is in the db we can add tags to it
00597 
00598           // first, if we want to import categories as tags, add them to the array
00599           if ( $inputs['category_import'] ) {
00600             $tags = array_merge( $tags, $categories );
00601           }
00602 
00603           // now for the tags!
00604           foreach ( $tags as $tag ) {
00605 
00606             // try to get the tag by slug, which is the key and therefore the most unique
00607             $t = Tags::get_by_slug( $tag->slug );
00608 
00609             // if we didn't get back a tag, create a new one
00610             if ( $t == false ) {
00611               $t = Tag::create( array(
00612                 'term' => $tag->slug,
00613                 'term_display' => $tag->name
00614               ) );
00615             }
00616 
00617             // now that we have a tag (one way or the other), associate this post with it
00618             $t->associate( 'post', $p->id );
00619 
00620           }
00621 
00622         }
00623         catch ( \Exception $e ) {
00624 
00625           EventLog::log( $e->getMessage(), 'err' );
00626 
00627           echo '<p class="error">' . _t( 'There was an error importing post %s. See the EventLog for the error message.', array( $post->post_title ) );
00628 
00629           echo '<p>' . _t( 'Rolling back changes&hellip;' ) . '</p>';
00630 
00631           // rollback all changes before we return so the import hasn't changed anything yet
00632           DB::rollback();
00633 
00634           // and return so they don't get AJAX to send them on to the next step
00635           return false;
00636 
00637         }
00638 
00639       }
00640 
00641 
00642       // if we've finished without an error, commit the import
00643       DB::commit();
00644 
00645       if ( $max < $num_posts ) {
00646 
00647         // if there are more posts to import
00648 
00649         // get the next ajax url
00650         $ajax_url = URL::get( 'auth_ajax', array( 'context' => 'wp_import_posts' ) );
00651 
00652         // bump the import index by one so we get a new batch next time
00653         $inputs['import_index']++;
00654 
00655 
00656       }
00657       else {
00658 
00659         // move on to importing comments
00660 
00661         // get the next ajax url
00662         $ajax_url = URL::get( 'auth_ajax', array( 'context' => 'wp_import_comments' ) );
00663 
00664         // reset the import index so we start at the first comment
00665         $inputs['import_index'] = 0;
00666 
00667       }
00668 
00669       // and spit out ajax to send them to the next step - posts!
00670       echo $this->get_ajax( $ajax_url, $inputs );
00671 
00672     }
00673 
00679     public function action_auth_ajax_wp_import_comments ( ) {
00680 
00681       // get the values post'd in
00682       $inputs = $_POST->filter_keys( array( 'db_name', 'db_host', 'db_user', 'db_pass', 'db_prefix', 'category_import', 'import_index' ) );
00683       $inputs = $inputs->getArrayCopy();
00684 
00685       // make sure we have all our default values
00686       $inputs = array_merge( $this->default_values, $inputs );
00687 
00688       // get the wpdb
00689       $wpdb = $this->wp_connect( $inputs['db_host'], $inputs['db_name'], $inputs['db_user'], $inputs['db_pass'] );
00690 
00691       // if we couldn't connect, error out
00692       if ( !$wpdb ) {
00693         EventLog::log( _t( 'Failed to import from "%s"', array( $inputs['db_name'] ) ) );
00694         Session::error( _t( 'Failed to import from "%s"', array( $inputs['db_name'] ) ) );
00695         echo '<p>' . _t( 'Failed to connect using the given database connection details.' ) . '</p>';
00696       }
00697 
00698       // we connected just fine, let's get moving!
00699 
00700       // begin a transaction. if we error out at any point, we want to roll back to before import began
00701       DB::begin_transaction();
00702 
00703       // fetch the number of comments from the wordpress database so we can batch things up
00704       $num_comments = $wpdb->get_value( 'select count(comment_id) from ' . $inputs['db_prefix'] . 'comments' );
00705 
00706       // figure out the LIMIT we're at
00707       $min = $inputs['import_index'] * IMPORT_BATCH;
00708       $max = min( $min + IMPORT_BATCH, $num_comments );   // for display only
00709 
00710 
00711       echo '<p>' . _t( 'Importing comments %1$d - %2$d of %3$d.', array( $min, $max, $num_comments ) ) . '</p>';
00712 
00713       // get all the imported users so we can link old comment authors to new comment authors
00714       $users = DB::get_results( 'select user_id, value from {userinfo} where name = :name', array( ':name' => 'wp_id' ) );
00715 
00716       // create an easy user map of old ID -> new ID
00717       $user_map = array();
00718       foreach ( $users as $info ) {
00719         $user_map[ $info->value ] = $info->user_id;
00720       }
00721 
00722       // get all the imported posts so we can link old post IDs to new post IDs
00723       $posts = DB::get_results( 'select post_id, value from {postinfo} where name = :name', array( ':name' => 'wp_id' ) );
00724 
00725       // create an easy post map of old ID -> new ID
00726       $post_map = array();
00727       foreach ( $posts as $info ) {
00728         $post_map[ $info->value ] = $info->post_id;
00729       }
00730 
00731       // get all the comment IDs we've imported so far to make sure we don't duplicate any
00732       $comment_map = DB::get_column( 'select value from {commentinfo} where name = :name', array( ':name' => 'wp_id' ) );
00733 
00734 
00735 
00736       // now we're ready to start importing comments
00737       $comments = $wpdb->get_results( 'select comment_id, comment_post_id, comment_author, comment_author_email, comment_author_url, comment_author_ip, comment_date, comment_content, comment_karma, comment_approved, comment_agent, comment_type, comment_parent, user_id from ' . $inputs['db_prefix'] . 'comments order by comment_id asc limit ' . $min . ', ' . IMPORT_BATCH );
00738 
00739       foreach ( $comments as $comment ) {
00740 
00741         // if this post is already in the list we've imported, skip it
00742         if ( in_array( $comment->id, $comment_map ) ) {
00743           continue;
00744         }
00745 
00746         // if the post this comment belongs to is not in the list of imported posts, skip it
00747         if ( !isset( $post_map[ $comment->comment_post_id ] ) ) {
00748           continue;
00749         }
00750 
00751         // create the new comment
00752         $c = new Comment( array(
00753           'content' => MultiByte::convert_encoding( $comment->comment_content ),
00754           'name' => MultiByte::convert_encoding( $comment->comment_author ),
00755           'email' => MultiByte::convert_encoding( $comment->comment_author_email ),
00756           'url' => MultiByte::convert_encoding( $comment->comment_author_url ),
00757           'date' => DateTime::create( $comment->comment_date ),
00758           'post_id' => $post_map[ $comment->comment_post_id ],
00759         ) );
00760 
00761         // figure out the comment type
00762         switch ( $comment->comment_type ) {
00763 
00764           case 'pingback':
00765             $c->type = Comment::type( 'pingback' );
00766             break;
00767 
00768           case 'trackback':
00769             $c->type = Comment::type( 'trackback' );
00770             break;
00771 
00772           default:
00773           case 'comment':
00774             $c->type = Comment::type( 'comment' );
00775             break;
00776 
00777         }
00778 
00779         // figure out the comment status
00780         switch ( $comment->comment_approved ) {
00781 
00782           case '1':
00783             $c->status = Comment::status( 'approved' );
00784             break;
00785 
00786           case '':
00787           case '0':
00788             $c->status = Comment::status( 'unapproved' );
00789             break;
00790 
00791           case 'spam':
00792             $c->status = Comment::status( 'spam' );
00793             break;
00794 
00795           default:
00796             // Comment::status() returns false if it doesn't recognize the status type
00797             $status = Comment::status( $comment->comment_status );    // store in a temp value because if you try and set ->status to an invalid value the Comment class freaks
00798 
00799             if ( $status == false ) {
00800               // we're not importing statuses we don't recognize - continue 2 to break out of the switch and the loop and continue to the next comment
00801               continue 2;
00802             }
00803             else {
00804               $c->status = $status;
00805             }
00806 
00807             break;
00808 
00809         }
00810 
00811         // save the old comment ID in info
00812         $c->info->wp_id = $comment->comment_id;
00813 
00814         // save the old post ID in info
00815         $c->info->wp_post_id = $comment->comment_post_id;
00816 
00817         // save the old comment karma - but only if it is something
00818         if ( $comment->comment_karma != '0' ) {
00819           $c->info->wp_karma = $comment->comment_karma;
00820         }
00821 
00822         // save the old comment user agent - but only if it is something
00823         if ( $comment->comment_agent != '' ) {
00824           $c->info->wp_agent = $comment->comment_agent;
00825         }
00826 
00827 
00828         // now that we've got all the pieces in place, save the comment
00829         try {
00830           $c->insert();
00831         }
00832         catch ( \Exception $e ) {
00833 
00834           EventLog::log( $e->getMessage(), 'err' );
00835 
00836           echo '<p class="error">' . _t( 'There was an error importing comment ID %d. See the EventLog for the error message.', array( $comment->comment_id ) );
00837 
00838           echo '<p>' . _t( 'Rolling back changes&hellip;' ) . '</p>';
00839 
00840           // rollback all changes before we return so the import hasn't changed anything yet
00841           DB::rollback();
00842 
00843           // and return so they don't get AJAX to send them on to the next step
00844           return false;
00845 
00846         }
00847 
00848       }
00849 
00850 
00851       // if we've finished without an error, commit the import
00852       DB::commit();
00853 
00854       if ( $max < $num_comments ) {
00855 
00856         // if there are more posts to import
00857 
00858         // get the next ajax url
00859         $ajax_url = URL::get( 'auth_ajax', array( 'context' => 'wp_import_comments' ) );
00860 
00861         // bump the import index by one so we get a new batch next time
00862         $inputs['import_index']++;
00863 
00864 
00865       }
00866       else {
00867 
00868         // display the completed message!
00869 
00870         EventLog::log( _t( 'Import completed from "%s"', array( $inputs['db_name'] ) ) );
00871         echo '<p>' . _t( 'Import is complete.' ) . '</p>';
00872 
00873         return;
00874 
00875       }
00876 
00877       // and spit out ajax to send them to the next step - posts!
00878       echo $this->get_ajax( $ajax_url, $inputs );
00879 
00880     }
00881 
00882 
00883   }
00884 
00885 ?>

Generated on Sun Aug 4 2013 12:51:44 for Habari by  doxygen 1.7.1