Changeset 10810 for trunk/wp-admin/import/livejournal.php
- Timestamp:
- 03/18/2009 02:43:45 AM (17 years ago)
- File:
-
- 1 edited
-
trunk/wp-admin/import/livejournal.php (modified) (58 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/wp-admin/import/livejournal.php
r10647 r10810 31 31 var $commentmap; 32 32 var $pointers = array(); 33 33 34 34 // This list taken from LJ, they don't appear to have an API for it 35 35 var $moods = array( '1' => 'aggravated', … … 194 194 <p><?php _e( 'Howdy! This importer allows you to connect directly to LiveJournal and download all your entries and comments' ) ?></p> 195 195 <p><?php _e( 'Enter your LiveJournal username and password below so we can connect to your account:' ) ?></p> 196 196 197 197 <table class="form-table"> 198 198 … … 206 206 <td><input type="password" name="lj_password" id="lj_password" class="regular-text" /></td> 207 207 </tr> 208 208 209 209 </table> 210 210 211 211 <p><?php _e( 'If you have any entries on LiveJournal which are marked as private, they will be password-protected when they are imported so that only people who know the password can see them.' ) ?></p> 212 212 <p><?php _e( "If you don't enter a password, ALL ENTRIES from your LiveJournal will be imported as public posts in WordPress." ) ?></p> … … 222 222 223 223 <p><?php _e( "<strong>WARNING:</strong> This can take a really long time if you have a lot of entries in your LiveJournal, or a lot of comments. Ideally, you should only start this process if you can leave your computer alone while it finishes the import." ) ?></p> 224 224 225 225 <p class="submit"> 226 226 <input type="submit" class="button-primary" value="<?php echo attribute_escape( __( 'Connect to LiveJournal and Import' ) ) ?>" /> 227 227 </p> 228 228 229 229 <p><?php _e( '<strong>NOTE:</strong> If the import process is interrupted for <em>any</em> reason, come back to this page and it will continue from where it stopped automatically.' ) ?></p> 230 230 … … 237 237 <?php 238 238 } 239 239 240 240 function download_post_meta() { 241 241 $total = (int) get_option( 'ljapi_total' ); … … 248 248 if ( !is_array( $sync_item_times ) ) 249 249 $sync_item_times = array(); 250 250 251 251 do { 252 252 $lastsync = date( 'Y-m-d H:i:s', strtotime( get_option( 'ljapi_lastsync' ) ) ); … … 254 254 if ( is_wp_error( $synclist ) ) 255 255 return $synclist; 256 256 257 257 // Keep track of if we've downloaded everything 258 258 $total = $synclist['total']; 259 259 $count = $synclist['count']; 260 260 261 261 foreach ( $synclist['syncitems'] as $event ) { 262 262 if ( substr( $event['item'], 0, 2 ) == 'L-' ) { … … 277 277 echo '<p>' . __( 'Post metadata has been downloaded, proceeding with posts...' ) . '</p>'; 278 278 } 279 279 280 280 function download_post_bodies() { 281 281 $imported_count = (int) get_option( 'ljapi_imported_count' ); … … 286 286 287 287 $count = 0; 288 echo '<ol>'; 288 echo '<ol>'; 289 289 do { 290 290 $lastsync = date( 'Y-m-d H:i:s', strtotime( get_option( 'ljapi_lastsync_posts' ) ) ); 291 291 292 292 // Get the batch of items that match up with the syncitems list 293 293 $itemlist = $this->lj_ixr( 'getevents', array( 'ver' => 1, … … 297 297 if ( is_wp_error( $itemlist ) ) 298 298 return $itemlist; 299 299 300 300 if ( $num = count( $itemlist['events'] ) ) { 301 301 for ( $e = 0; $e < count( $itemlist['events'] ); $e++ ) { … … 315 315 $count++; 316 316 } while ( $num > 0 && $count < 3 ); // Doing up to 3 requests at a time to avoid memory problems 317 317 318 318 // Used so that step1 knows when to stop posting back on itself 319 319 update_option( 'ljapi_last_sync_count', $num ); 320 320 321 321 // Counter just used to show progress to user 322 322 update_option( 'ljapi_post_batch', ( (int) get_option( 'ljapi_post_batch' ) + 1 ) ); … … 324 324 echo '</ol>'; 325 325 } 326 326 327 327 function import_post( $post ) { 328 328 global $wpdb; 329 329 330 330 // Make sure we haven't already imported this one 331 331 if ( $this->get_wp_post_ID( $post['itemid'] ) ) 332 332 return; 333 333 334 334 $user = wp_get_current_user(); 335 335 $post_author = $user->ID; … … 342 342 if ( 18 == strlen( $post_date ) ) 343 343 $post_date = substr( $post_date, 0, 10 ) . ' ' . substr( $post_date, 10 ); 344 344 345 345 // Cleaning up and linking the title 346 346 $post_title = isset( $post['subject'] ) ? trim( $post['subject'] ) : ''; … … 348 348 $post_title = strip_tags( $post_title ); // Can't have tags in the title in WP 349 349 $post_title = $wpdb->escape( $post_title ); 350 350 351 351 // Clean up content 352 352 $post_content = $post['event']; … … 364 364 $post_content = force_balance_tags( $post_content ); 365 365 $post_content = $wpdb->escape( $post_content ); 366 366 367 367 // Handle any tags associated with the post 368 368 $tags_input = !empty( $post['props']['taglist'] ) ? $post['props']['taglist'] : ''; 369 369 370 370 // Check if comments are closed on this post 371 371 $comment_status = !empty( $post['props']['opt_nocomments'] ) ? 'closed' : 'open'; … … 388 388 return new WP_Error( 'insert_post_failed', __( 'Failed to create post.' ) ); 389 389 } 390 390 391 391 // Handle all the metadata for this post 392 392 $this->insert_postmeta( $post_id, $post ); … … 394 394 echo '</li>'; 395 395 } 396 396 397 397 // Convert lj-user tags to links to that user 398 398 function translate_lj_user( $str ) { 399 399 return preg_replace( '|<lj\s+user\s*=\s*["\']([\w-]+)["\']>|', '<a href="http://$1.livejournal.com/" class="lj-user">$1</a>', $str ); 400 400 } 401 401 402 402 function insert_postmeta( $post_id, $post ) { 403 403 // Need the original LJ id for comments 404 404 add_post_meta( $post_id, 'lj_itemid', $post['itemid'] ); 405 405 406 406 // And save the permalink on LJ in case we want to link back or something 407 407 add_post_meta( $post_id, 'lj_permalink', $post['url'] ); 408 408 409 409 // Supports the following "props" from LJ, saved as lj_<prop_name> in wp_postmeta 410 410 // Adult Content - adult_content … … 425 425 } 426 426 } 427 427 428 428 // Set up a session (authenticate) with LJ 429 429 function get_session() { … … 434 434 return new WP_Http_Cookie( array( 'name' => 'ljsession', 'value' => $cookie['ljsession'] ) ); 435 435 } 436 436 437 437 // Loops through and gets comment meta from LJ in batches 438 438 function download_comment_meta() { … … 440 440 if ( is_wp_error( $cookie ) ) 441 441 return $cookie; 442 442 443 443 // Load previous state (if any) 444 444 $this->usermap = (array) get_option( 'ljapi_usermap' ); 445 445 $maxid = get_option( 'ljapi_maxid' ) ? get_option( 'ljapi_maxid' ) : 1; 446 446 $highest_id = get_option( 'ljapi_highest_id' ) ? get_option( 'ljapi_highest_id' ) : 0; 447 447 448 448 // We need to loop over the metadata request until we have it all 449 449 while ( $maxid > $highest_id ) { … … 453 453 if ( is_wp_error( $results ) ) 454 454 return new WP_Error( 'comment_meta', __( 'Failed to retrieve comment meta information from LiveJournal. Please try again soon.' ) ); 455 455 456 456 $results = wp_remote_retrieve_body( $results ); 457 457 458 458 // Get the maxid so we know if we have them all yet 459 459 preg_match( '|<maxid>(\d+)</maxid>|', $results, $matches ); … … 466 466 } 467 467 $maxid = !empty( $matches[1] ) ? $matches[1] : $maxid; 468 468 469 469 // Parse comments and get highest id available 470 470 preg_match_all( '|<comment id=\'(\d+)\'|is', $results, $matches ); … … 478 478 foreach ( $matches[1] as $count => $userid ) 479 479 $this->usermap[$userid] = $matches[2][$count]; // need this in memory for translating ids => names 480 480 481 481 wp_cache_flush(); 482 482 } … … 486 486 update_option( 'ljapi_maxid', $maxid ); 487 487 update_option( 'ljapi_highest_id', $highest_id ); 488 488 489 489 echo '<p>' . __( ' Comment metadata downloaded successfully, proceeding with comment bodies...' ) . '</p>'; 490 490 491 491 return true; 492 492 } 493 493 494 494 // Downloads actual comment bodies from LJ 495 495 // Inserts them all directly to the DB, with additional info stored in "spare" fields … … 499 499 if ( is_wp_error( $cookie ) ) 500 500 return $cookie; 501 501 502 502 // Load previous state (if any) 503 503 $this->usermap = (array) get_option( 'ljapi_usermap' ); … … 507 507 while ( $maxid > $highest_id && $loop < 5 ) { // We do 5 loops per call to avoid memory limits 508 508 $loop++; 509 509 510 510 // Get a batch of comments, using the highest_id we've already got as a starting point 511 511 $results = wp_remote_get( $this->comments_url . '?get=comment_body&startid=' . ( $highest_id + 1 ), … … 513 513 if ( is_wp_error( $results ) ) 514 514 return new WP_Error( 'comment_bodies', __( 'Failed to retrieve comment bodies from LiveJournal. Please try again soon.' ) ); 515 515 516 516 $results = wp_remote_retrieve_body( $results ); 517 517 518 518 // Parse out each comment and insert directly 519 519 preg_match_all( '|<comment id=\'(\d+)\'.*</comment>|iUs', $results, $matches ); … … 524 524 update_option( 'ljapi_highest_comment_id', $highest_id ); 525 525 } 526 526 527 527 $comment = $matches[0][$c]; 528 528 … … 537 537 clean_comment_cache( $id ); 538 538 } 539 539 540 540 // Clear cache to preseve memory 541 541 wp_cache_flush(); 542 542 } 543 543 // endwhile - all comments downloaded and ready for bulk processing 544 544 545 545 // Counter just used to show progress to user 546 546 update_option( 'ljapi_comment_batch', ( (int) get_option( 'ljapi_comment_batch' ) + 1 ) ); 547 547 548 548 return true; 549 549 } 550 550 551 551 // Takes a block of XML and parses out all the elements of the comment 552 552 function parse_comment( $comment ) { 553 553 global $wpdb; 554 554 555 555 // Get the top-level attributes 556 556 preg_match( '|<comment([^>]+)>|i', $comment, $attribs ); … … 565 565 preg_match( '| state=\'([SDFA])\'|i', $attribs[1], $matches ); // optional 566 566 $lj_comment_state = isset( $matches[1] ) ? $matches[1] : 'A'; 567 567 568 568 // Clean up "subject" - this will become the first line of the comment in WP 569 569 preg_match( '|<subject>(.*)</subject>|is', $comment, $matches ); … … 573 573 $comment_subject = ''; 574 574 } 575 575 576 576 // Get the body and HTMLize it 577 577 preg_match( '|<body>(.*)</body>|is', $comment, $matches ); … … 584 584 $comment_content = preg_replace_callback( '|<(/?[A-Z]+)|', create_function( '$match', 'return "<" . strtolower( $match[1] );' ), $comment_content ); 585 585 $comment_content = $wpdb->escape( trim( $comment_content ) ); 586 586 587 587 // Get and convert the date 588 588 preg_match( '|<date>(.*)</date>|i', $comment, $matches ); 589 589 $comment_date = trim( str_replace( array( 'T', 'Z' ), ' ', $matches[1] ) ); 590 590 591 591 // Grab IP if available 592 592 preg_match( '|<property name=\'poster_ip\'>(.*)</property>|i', $comment, $matches ); // optional 593 593 $comment_author_IP = isset( $matches[1] ) ? $matches[1] : ''; 594 594 595 595 // Try to get something useful for the comment author, especially if it was "my" comment 596 596 $author = ( empty( $comment_author_ID ) || empty( $this->usermap[$comment_author_ID] ) || substr( $this->usermap[$comment_author_ID], 0, 4 ) == 'ext_' ) ? __( 'Anonymous' ) : $this->usermap[$comment_author_ID]; … … 602 602 } else { 603 603 $user_id = 0; 604 $url = ( __( 'Anonymous' ) == $author ) ? '' : 'http://' . $author . '.livejournal.com/'; 605 } 606 604 $url = ( __( 'Anonymous' ) == $author ) ? '' : 'http://' . $author . '.livejournal.com/'; 605 } 606 607 607 // Send back the array of details 608 608 return array( 'lj_comment_ID' => $lj_comment_ID, … … 624 624 ); 625 625 } 626 627 626 627 628 628 // Gets the post_ID that a LJ post has been saved as within WP 629 629 function get_wp_post_ID( $post ) { 630 630 global $wpdb; 631 631 632 632 if ( empty( $this->postmap[$post] ) ) 633 633 $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 634 635 635 return $this->postmap[$post]; 636 636 } 637 637 638 638 // Gets the comment_ID that a LJ comment has been saved as within WP 639 639 function get_wp_comment_ID( $comment ) { … … 643 643 return $this->commentmap[$comment]; 644 644 } 645 645 646 646 function lj_ixr() { 647 647 if ( $challenge = $this->ixr->query( 'LJ.XMLRPC.getchallenge' ) ) { … … 656 656 return new WP_Error( 'IXR', __( 'LiveJournal is not responding to authentication requests. Please wait a while and then try again.' ) ); 657 657 } 658 658 659 659 $args = func_get_args(); 660 660 $method = array_shift( $args ); … … 667 667 } 668 668 } 669 669 670 670 function dispatch() { 671 671 if ( empty( $_REQUEST['step'] ) ) … … 675 675 676 676 $this->header(); 677 677 678 678 switch ( $step ) { 679 679 case -1 : … … 712 712 $this->password = get_option( 'ljapi_password' ); 713 713 } 714 714 715 715 // This is the password to set on protected posts 716 716 if ( !empty( $_POST['protected_password'] ) ) { … … 720 720 $this->protected_password = get_option( 'ljapi_protected_password' ); 721 721 } 722 722 723 723 // Login to confirm the details are correct 724 724 if ( empty( $this->username ) || empty( $this->password ) ) { … … 746 746 update_option( 'ljapi_verified', 'yes' ); 747 747 } 748 748 749 749 // Set up some options to avoid them autoloading (these ones get big) 750 750 add_option( 'ljapi_sync_item_times', '', '', 'no' ); 751 751 add_option( 'ljapi_usermap', '', '', 'no' ); 752 752 update_option( 'ljapi_comment_batch', 0 ); 753 753 754 754 return true; 755 755 } … … 776 776 } 777 777 } 778 778 779 779 echo '<div id="ljapi-status">'; 780 780 echo '<h3>' . __( 'Importing Posts' ) . '</h3>'; … … 786 786 } 787 787 ob_flush(); flush(); 788 788 789 789 if ( !get_option( 'ljapi_lastsync' ) || '1900-01-01 00:00:00' == get_option( 'ljapi_lastsync' ) ) { 790 790 // We haven't downloaded meta yet, so do that first … … 828 828 echo '</div>'; 829 829 } 830 830 831 831 // Download comments to local XML 832 832 function step2() { … … 836 836 $this->password = get_option( 'ljapi_password' ); 837 837 $this->ixr = new IXR_Client( $this->ixr_url, false, 80, 30 ); 838 838 839 839 echo '<div id="ljapi-status">'; 840 840 echo '<h3>' . __( 'Downloading Comments' ) . '</h3>'; 841 841 echo '<p>' . __( 'Now we will download your comments so we can import them (this could take a <strong>long</strong> time if you have lots of comments)...' ) . '</p>'; 842 842 ob_flush(); flush(); 843 843 844 844 if ( !get_option( 'ljapi_usermap' ) ) { 845 845 // We haven't downloaded meta yet, so do that first … … 878 878 echo '</div>'; 879 879 } 880 880 881 881 // Re-thread comments already in the DB 882 882 function step3() { … … 884 884 set_time_limit( 0 ); 885 885 update_option( 'ljapi_step', 3 ); 886 886 887 887 echo '<div id="ljapi-status">'; 888 888 echo '<h3>' . __( 'Threading Comments' ) . '</h3>'; 889 889 echo '<p>' . __( 'We are now re-building the threading of your comments (this can also take a while if you have lots of comments)...' ) . '</p>'; 890 890 ob_flush(); flush(); 891 891 892 892 // Only bother adding indexes if they have over 5000 comments (arbitrary number) 893 893 $imported_comments = $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->comments} WHERE comment_type = 'livejournal'" ); … … 900 900 add_clean_index( $wpdb->comments, 'comment_agent' ); 901 901 } 902 902 903 903 // Get LJ comments, which haven't been threaded yet, 5000 at a time and thread them 904 904 while ( $comments = $wpdb->get_results( "SELECT comment_ID, comment_agent FROM {$wpdb->comments} WHERE comment_type = 'livejournal' AND comment_agent != '0' LIMIT 5000", OBJECT ) ) { 905 905 foreach ( $comments as $comment ) { 906 $wpdb->update( $wpdb->comments, 907 array( 'comment_parent' => $this->get_wp_comment_ID( $comment->comment_agent ), 'comment_type' => 'livejournal-done' ), 906 $wpdb->update( $wpdb->comments, 907 array( 'comment_parent' => $this->get_wp_comment_ID( $comment->comment_agent ), 'comment_type' => 'livejournal-done' ), 908 908 array( 'comment_ID' => $comment->comment_ID ) ); 909 909 } … … 911 911 $wpdb->flush(); 912 912 } 913 913 914 914 // Revert the comments table back to normal and optimize it to reclaim space 915 915 if ( $added_indices ) { … … 919 919 $wpdb->query( "OPTIMIZE TABLE {$wpdb->comments}" ); 920 920 } 921 921 922 922 // Clean up database and we're out 923 923 $this->cleanup(); … … 930 930 echo '</div>'; 931 931 } 932 932 933 933 // Output an error message with a button to try again. 934 934 function throw_error( $error, $step ) { … … 936 936 echo $this->next_step( $step, __( 'Try Again' ) ); 937 937 } 938 938 939 939 // Returns the HTML for a link to the next page 940 940 function next_step( $next_step, $label, $id = 'ljapi-next-form' ) { … … 945 945 $str .= '<p><input type="submit" class="button-primary" value="' . attribute_escape( $label ) . '" /> <span id="auto-message"></span></p>'; 946 946 $str .= '</form>'; 947 947 948 948 return $str; 949 949 } 950 950 951 951 // Automatically submit the specified form after $seconds 952 952 // Include a friendly countdown in the element with id=$msg … … 957 957 ljapi_msg(); 958 958 }); 959 959 960 960 function ljapi_msg() { 961 961 str = '<?php _e( "Continuing in %d" ) ?>'; … … 975 975 </script><?php 976 976 } 977 977 978 978 // Automatically submit the form with #id to continue the process 979 979 // Hide any submit buttons to avoid people clicking them … … 985 985 ljapi_msg(); 986 986 }); 987 987 988 988 function ljapi_msg() { 989 989 str = '<?php _e( "Continuing in %d" ) ?>'; … … 1012 1012 function cleanup() { 1013 1013 global $wpdb; 1014 1014 1015 1015 delete_option( 'ljapi_username' ); 1016 1016 delete_option( 'ljapi_password' ); … … 1031 1031 delete_option( 'ljapi_comment_batch' ); 1032 1032 delete_option( 'ljapi_step' ); 1033 1034 $wpdb->update( $wpdb->comments, 1035 array( 'comment_karma' => 0, 'comment_agent' => 'WP LJ Importer', 'comment_type' => '' ), 1033 1034 $wpdb->update( $wpdb->comments, 1035 array( 'comment_karma' => 0, 'comment_agent' => 'WP LJ Importer', 'comment_type' => '' ), 1036 1036 array( 'comment_type' => 'livejournal-done' ) ); 1037 $wpdb->update( $wpdb->comments, 1038 array( 'comment_karma' => 0, 'comment_agent' => 'WP LJ Importer', 'comment_type' => '' ), 1037 $wpdb->update( $wpdb->comments, 1038 array( 'comment_karma' => 0, 'comment_agent' => 'WP LJ Importer', 'comment_type' => '' ), 1039 1039 array( 'comment_type' => 'livejournal' ) ); 1040 1040 } 1041 1041 1042 1042 function LJ_API_Import() { 1043 1043 $this->__construct(); 1044 1044 } 1045 1045 1046 1046 function __construct() { 1047 1047 // Nothing
Note: See TracChangeset
for help on using the changeset viewer.