2005-12-28 15:24:12 -05:00
< ? php
2009-02-10 14:34:52 -05:00
2008-08-14 02:30:38 -04:00
/**
2009-02-04 13:24:02 -05:00
* LiveJournal API Importer
2008-08-14 02:30:38 -04:00
*
* @ package WordPress
* @ subpackage Importer
*/
2005-12-28 15:24:12 -05:00
2009-02-04 13:24:02 -05:00
// XML-RPC library for communicating with LiveJournal API
require_once ( ABSPATH . WPINC . '/class-IXR.php' );
2008-08-14 02:30:38 -04:00
/**
2009-02-04 13:24:02 -05:00
* LiveJournal API Importer class
2008-08-14 02:30:38 -04:00
*
2009-02-04 13:24:02 -05:00
* Imports your LiveJournal contents into WordPress using the LJ API
2008-08-14 02:30:38 -04:00
*
2009-02-17 14:58:03 -05:00
* @ since 2.8
2008-08-14 02:30:38 -04:00
*/
2009-02-04 13:24:02 -05:00
class LJ_API_Import {
2005-12-28 15:24:12 -05:00
2009-02-04 13:24:02 -05:00
var $comments_url = 'http://www.livejournal.com/export_comments.bml' ;
var $ixr_url = 'http://www.livejournal.com/interface/xmlrpc' ;
var $ixr ;
var $username ;
var $password ;
var $comment_meta ;
var $comments ;
var $usermap ;
var $postmap ;
2009-02-10 14:34:52 -05:00
var $commentmap ;
2009-02-04 13:24:02 -05:00
var $pointers = array ();
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
// This list taken from LJ, they don't appear to have an API for it
var $moods = array ( '1' => 'aggravated' ,
'10' => 'discontent' ,
'100' => 'rushed' ,
'101' => 'contemplative' ,
'102' => 'nerdy' ,
'103' => 'geeky' ,
'104' => 'cynical' ,
'105' => 'quixotic' ,
'106' => 'crazy' ,
'107' => 'creative' ,
'108' => 'artistic' ,
'109' => 'pleased' ,
'11' => 'energetic' ,
'110' => 'bitchy' ,
'111' => 'guilty' ,
'112' => 'irritated' ,
'113' => 'blank' ,
'114' => 'apathetic' ,
'115' => 'dorky' ,
'116' => 'impressed' ,
'117' => 'naughty' ,
'118' => 'predatory' ,
'119' => 'dirty' ,
'12' => 'enraged' ,
'120' => 'giddy' ,
'121' => 'surprised' ,
'122' => 'shocked' ,
'123' => 'rejected' ,
'124' => 'numb' ,
'125' => 'cheerful' ,
'126' => 'good' ,
'127' => 'distressed' ,
'128' => 'intimidated' ,
'129' => 'crushed' ,
'13' => 'enthralled' ,
'130' => 'devious' ,
'131' => 'thankful' ,
'132' => 'grateful' ,
'133' => 'jealous' ,
'134' => 'nervous' ,
'14' => 'exhausted' ,
'15' => 'happy' ,
'16' => 'high' ,
'17' => 'horny' ,
'18' => 'hungry' ,
'19' => 'infuriated' ,
'2' => 'angry' ,
'20' => 'irate' ,
'21' => 'jubilant' ,
'22' => 'lonely' ,
'23' => 'moody' ,
'24' => 'pissed off' ,
'25' => 'sad' ,
'26' => 'satisfied' ,
'27' => 'sore' ,
'28' => 'stressed' ,
'29' => 'thirsty' ,
'3' => 'annoyed' ,
'30' => 'thoughtful' ,
'31' => 'tired' ,
'32' => 'touched' ,
'33' => 'lazy' ,
'34' => 'drunk' ,
'35' => 'ditzy' ,
'36' => 'mischievous' ,
'37' => 'morose' ,
'38' => 'gloomy' ,
'39' => 'melancholy' ,
'4' => 'anxious' ,
'40' => 'drained' ,
'41' => 'excited' ,
'42' => 'relieved' ,
'43' => 'hopeful' ,
'44' => 'amused' ,
'45' => 'determined' ,
'46' => 'scared' ,
'47' => 'frustrated' ,
'48' => 'indescribable' ,
'49' => 'sleepy' ,
'5' => 'bored' ,
'51' => 'groggy' ,
'52' => 'hyper' ,
'53' => 'relaxed' ,
'54' => 'restless' ,
'55' => 'disappointed' ,
'56' => 'curious' ,
'57' => 'mellow' ,
'58' => 'peaceful' ,
'59' => 'bouncy' ,
'6' => 'confused' ,
'60' => 'nostalgic' ,
'61' => 'okay' ,
'62' => 'rejuvenated' ,
'63' => 'complacent' ,
'64' => 'content' ,
'65' => 'indifferent' ,
'66' => 'silly' ,
'67' => 'flirty' ,
'68' => 'calm' ,
'69' => 'refreshed' ,
'7' => 'crappy' ,
'70' => 'optimistic' ,
'71' => 'pessimistic' ,
'72' => 'giggly' ,
'73' => 'pensive' ,
'74' => 'uncomfortable' ,
'75' => 'lethargic' ,
'76' => 'listless' ,
'77' => 'recumbent' ,
'78' => 'exanimate' ,
'79' => 'embarrassed' ,
'8' => 'cranky' ,
'80' => 'envious' ,
'81' => 'sympathetic' ,
'82' => 'sick' ,
'83' => 'hot' ,
'84' => 'cold' ,
'85' => 'worried' ,
'86' => 'loved' ,
'87' => 'awake' ,
'88' => 'working' ,
'89' => 'productive' ,
'9' => 'depressed' ,
'90' => 'accomplished' ,
'91' => 'busy' ,
'92' => 'blah' ,
'93' => 'full' ,
'95' => 'grumpy' ,
'96' => 'weird' ,
'97' => 'nauseated' ,
'98' => 'ecstatic' ,
'99' => 'chipper' );
2005-12-28 15:24:12 -05:00
function header () {
echo '<div class="wrap">' ;
2008-11-26 08:51:25 -05:00
screen_icon ();
2009-02-04 13:24:02 -05:00
echo '<h2>' . __ ( 'Import LiveJournal' ) . '</h2>' ;
2005-12-28 15:24:12 -05:00
}
function footer () {
echo '</div>' ;
}
2009-02-04 12:47:50 -05:00
function greet () {
2009-02-04 13:24:02 -05:00
?>
< div class = " narrow " >
< form action = " admin.php?import=livejournal " method = " post " >
< ? php wp_nonce_field ( 'lj-api-import' ) ?>
< ? php if ( get_option ( 'ljapi_username' ) && get_option ( 'ljapi_password' ) ) : ?>
< input type = " hidden " name = " step " value = " <?php echo get_option( 'ljapi_step' ) ?> " />
< p >< ? php _e ( 'It looks like you attempted to import your LiveJournal posts previously and got interrupted.' ) ?> </p>
< p class = " submit " >
< input type = " submit " class = " button-primary " value = " <?php echo attribute_escape( __( 'Continue previous import' ) ) ?> " />
</ p >
2009-03-17 22:46:32 -04:00
< p class = " submitbox " >< a href = " <?php echo clean_url( $_SERVER['PHP_SELF'] . '?import=livejournal&step=-1&_wpnonce=' . wp_create_nonce( 'lj-api-import' ) . '&_wp_http_referer=' . attribute_escape( $_SERVER['REQUEST_URI'] )) ?> " class = " deletion submitdelete " >< ? php _e ( 'Cancel & start a new import' ) ?> </a></p>
2009-02-04 13:24:02 -05:00
< p >
< ? php else : ?>
< input type = " hidden " name = " step " value = " 1 " />
2009-02-17 14:58:03 -05:00
< input type = " hidden " name = " login " value = " true " />
2009-02-04 13:24:02 -05:00
< p >< ? php _e ( 'Howdy! This importer allows you to connect directly to LiveJournal and download all your entries and comments' ) ?> </p>
< p >< ? php _e ( 'Enter your LiveJournal username and password below so we can connect to your account:' ) ?> </p>
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
< table class = " form-table " >
2009-02-04 12:47:50 -05:00
2009-02-04 13:24:02 -05:00
< tr >
< th scope = " row " >< label for = " lj_username " >< ? php _e ( 'LiveJournal Username' ) ?> </label></th>
< td >< input type = " text " name = " lj_username " id = " lj_username " class = " regular-text " /></ td >
</ tr >
2005-12-28 15:24:12 -05:00
2009-02-04 13:24:02 -05:00
< tr >
< th scope = " row " >< label for = " lj_password " >< ? php _e ( 'LiveJournal Password' ) ?> </label></th>
< td >< input type = " password " name = " lj_password " id = " lj_password " class = " regular-text " /></ td >
</ tr >
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
</ table >
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
< 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>
< p >< ? php _e ( " If you don't enter a password, ALL ENTRIES from your LiveJournal will be imported as public posts in WordPress. " ) ?> </p>
< p >< ? php _e ( 'Enter the password you would like to use for all protected entries here:' ) ?> </p>
< table class = " form-table " >
2009-02-04 12:47:50 -05:00
2009-02-04 13:24:02 -05:00
< tr >
< th scope = " row " >< label for = " protected_password " >< ? php _e ( 'Protected Post Password' ) ?> </label></th>
< td >< input type = " text " name = " protected_password " id = " protected_password " class = " regular-text " /></ td >
</ tr >
</ table >
2005-12-28 15:24:12 -05:00
2009-02-04 13:24:02 -05:00
< 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>
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
< p class = " submit " >
< input type = " submit " class = " button-primary " value = " <?php echo attribute_escape( __( 'Connect to LiveJournal and Import' ) ) ?> " />
</ p >
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
< 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>
2009-02-10 14:34:52 -05:00
< noscript >
< p >< ? php _e ( '<strong>NOTE:</strong> You appear to have JavaScript disabled, so you will need to manually click through each step of this importer. If you enable JavaScript, it will step through automatically.' ) ?> </p>
</ noscript >
2009-02-04 13:24:02 -05:00
< ? php endif ; ?>
</ form >
</ div >
< ? php
}
2009-03-17 22:43:45 -04:00
2009-02-17 14:58:03 -05:00
function download_post_meta () {
2009-02-04 13:24:02 -05:00
$total = ( int ) get_option ( 'ljapi_total' );
$count = ( int ) get_option ( 'ljapi_count' );
$lastsync = get_option ( 'ljapi_lastsync' );
if ( ! $lastsync ) {
update_option ( 'ljapi_lastsync' , '1900-01-01 00:00:00' );
}
$sync_item_times = get_option ( 'ljapi_sync_item_times' );
if ( ! is_array ( $sync_item_times ) )
$sync_item_times = array ();
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
do {
$lastsync = date ( 'Y-m-d H:i:s' , strtotime ( get_option ( 'ljapi_lastsync' ) ) );
$synclist = $this -> lj_ixr ( 'syncitems' , array ( 'ver' => 1 , 'lastsync' => $lastsync ) );
2009-02-17 14:58:03 -05:00
if ( is_wp_error ( $synclist ) )
return $synclist ;
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
// Keep track of if we've downloaded everything
$total = $synclist [ 'total' ];
$count = $synclist [ 'count' ];
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
foreach ( $synclist [ 'syncitems' ] as $event ) {
if ( substr ( $event [ 'item' ], 0 , 2 ) == 'L-' ) {
$sync_item_times [ str_replace ( 'L-' , '' , $event [ 'item' ] ) ] = $event [ 'time' ];
2009-02-17 14:58:03 -05:00
if ( $event [ 'time' ] > $lastsync ) {
2009-02-04 13:24:02 -05:00
$lastsync = $event [ 'time' ];
2009-02-17 14:58:03 -05:00
update_option ( 'ljapi_lastsync' , $lastsync );
}
2009-02-04 13:24:02 -05:00
}
}
} while ( $total > $count );
// endwhile - all post meta is cached locally
2009-02-17 14:58:03 -05:00
unset ( $synclist );
2009-02-10 14:34:52 -05:00
update_option ( 'ljapi_sync_item_times' , $sync_item_times );
update_option ( 'ljapi_total' , $total );
update_option ( 'ljapi_count' , $count );
echo '<p>' . __ ( 'Post metadata has been downloaded, proceeding with posts...' ) . '</p>' ;
2009-02-17 14:58:03 -05:00
}
2009-03-17 22:43:45 -04:00
2009-02-17 14:58:03 -05:00
function download_post_bodies () {
$imported_count = ( int ) get_option ( 'ljapi_imported_count' );
$sync_item_times = get_option ( 'ljapi_sync_item_times' );
$lastsync = get_option ( 'ljapi_lastsync_posts' );
2009-02-04 13:24:02 -05:00
if ( ! $lastsync )
update_option ( 'ljapi_lastsync_posts' , date ( 'Y-m-d H:i:s' , 0 ) );
2009-02-17 14:58:03 -05:00
$count = 0 ;
2009-03-17 22:43:45 -04:00
echo '<ol>' ;
2009-02-04 13:24:02 -05:00
do {
$lastsync = date ( 'Y-m-d H:i:s' , strtotime ( get_option ( 'ljapi_lastsync_posts' ) ) );
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
// Get the batch of items that match up with the syncitems list
$itemlist = $this -> lj_ixr ( 'getevents' , array ( 'ver' => 1 ,
'selecttype' => 'syncitems' ,
'lineendings' => 'pc' ,
'lastsync' => $lastsync ) );
if ( is_wp_error ( $itemlist ) )
return $itemlist ;
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
if ( $num = count ( $itemlist [ 'events' ] ) ) {
2009-02-17 14:58:03 -05:00
for ( $e = 0 ; $e < count ( $itemlist [ 'events' ] ); $e ++ ) {
$event = $itemlist [ 'events' ][ $e ];
2009-02-04 13:24:02 -05:00
$imported_count ++ ;
2009-02-17 14:58:03 -05:00
$inserted = $this -> import_post ( $event );
if ( is_wp_error ( $inserted ) )
return $inserted ;
2009-02-04 13:24:02 -05:00
if ( $sync_item_times [ $event [ 'itemid' ] ] > $lastsync )
$lastsync = $sync_item_times [ $event [ 'itemid' ] ];
2009-02-17 14:58:03 -05:00
wp_cache_flush ();
2009-02-04 13:24:02 -05:00
}
update_option ( 'ljapi_lastsync_posts' , $lastsync );
update_option ( 'ljapi_imported_count' , $imported_count );
update_option ( 'ljapi_last_sync_count' , $num );
}
2009-02-17 14:58:03 -05:00
$count ++ ;
} while ( $num > 0 && $count < 3 ); // Doing up to 3 requests at a time to avoid memory problems
2009-03-17 22:43:45 -04:00
2009-02-17 14:58:03 -05:00
// Used so that step1 knows when to stop posting back on itself
update_option ( 'ljapi_last_sync_count' , $num );
2009-03-17 22:43:45 -04:00
2009-02-17 14:58:03 -05:00
// Counter just used to show progress to user
update_option ( 'ljapi_post_batch' , ( ( int ) get_option ( 'ljapi_post_batch' ) + 1 ) );
2005-12-28 15:24:12 -05:00
2009-02-04 13:24:02 -05:00
echo '</ol>' ;
}
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
function import_post ( $post ) {
global $wpdb ;
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
// Make sure we haven't already imported this one
if ( $this -> get_wp_post_ID ( $post [ 'itemid' ] ) )
return ;
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
$user = wp_get_current_user ();
2009-02-10 14:34:52 -05:00
$post_author = $user -> ID ;
$post [ 'security' ] = ! empty ( $post [ 'security' ] ) ? $post [ 'security' ] : '' ;
$post_status = ( 'private' == trim ( $post [ 'security' ] ) ) ? 'private' : 'publish' ; // Only me
$post_password = ( 'usemask' == trim ( $post [ 'security' ] ) ) ? $this -> protected_password : '' ; // "Friends" via password
2005-12-28 15:24:12 -05:00
2009-02-04 13:24:02 -05:00
// For some reason, LJ sometimes sends a date as "2004-04-1408:38:00" (no space btwn date/time)
$post_date = $post [ 'eventtime' ];
if ( 18 == strlen ( $post_date ) )
$post_date = substr ( $post_date , 0 , 10 ) . ' ' . substr ( $post_date , 10 );
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
// Cleaning up and linking the title
2009-02-10 14:34:52 -05:00
$post_title = isset ( $post [ 'subject' ] ) ? trim ( $post [ 'subject' ] ) : '' ;
2009-02-04 13:24:02 -05:00
$post_title = $this -> translate_lj_user ( $post_title ); // Translate it, but then we'll strip the link
$post_title = strip_tags ( $post_title ); // Can't have tags in the title in WP
$post_title = $wpdb -> escape ( $post_title );
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
// Clean up content
$post_content = $post [ 'event' ];
$post_content = preg_replace_callback ( '|<(/?[A-Z]+)|' , create_function ( '$match' , 'return "<" . strtolower( $match[1] );' ), $post_content );
// XHTMLize some tags
$post_content = str_replace ( '<br>' , '<br />' , $post_content );
$post_content = str_replace ( '<hr>' , '<hr />' , $post_content );
// lj-cut ==> <!--more-->
$post_content = preg_replace ( '|<lj-cut text="([^"]*)">|is' , '<!--more $1-->' , $post_content );
$post_content = str_replace ( array ( '<lj-cut>' , '</lj-cut>' ), array ( '<!--more-->' , '' ), $post_content );
$first = strpos ( $post_content , '<!--more' );
$post_content = substr ( $post_content , 0 , $first + 1 ) . preg_replace ( '|<!--more(.*)?-->|sUi' , '' , substr ( $post_content , $first + 1 ) );
// lj-user ==> a href
$post_content = $this -> translate_lj_user ( $post_content );
2009-04-06 14:33:50 -04:00
//$post_content = force_balance_tags( $post_content );
2009-02-04 13:24:02 -05:00
$post_content = $wpdb -> escape ( $post_content );
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
// Handle any tags associated with the post
$tags_input = ! empty ( $post [ 'props' ][ 'taglist' ] ) ? $post [ 'props' ][ 'taglist' ] : '' ;
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
// Check if comments are closed on this post
$comment_status = ! empty ( $post [ 'props' ][ 'opt_nocomments' ] ) ? 'closed' : 'open' ;
2009-01-31 13:41:35 -05:00
2009-02-04 13:24:02 -05:00
echo '<li>' ;
if ( $post_id = post_exists ( $post_title , $post_content , $post_date ) ) {
printf ( __ ( 'Post <strong>%s</strong> already exists.' ), stripslashes ( $post_title ) );
} else {
2009-02-17 14:58:03 -05:00
printf ( __ ( 'Imported post <strong>%s</strong>...' ), stripslashes ( $post_title ) );
2009-02-04 13:24:02 -05:00
$postdata = compact ( 'post_author' , 'post_date' , 'post_content' , 'post_title' , 'post_status' , 'post_password' , 'tags_input' , 'comment_status' );
2009-02-17 14:58:03 -05:00
$post_id = wp_insert_post ( $postdata , true );
if ( is_wp_error ( $post_id ) ) {
if ( 'empty_content' == $post_id -> get_error_code () )
return ; // Silent skip on "empty" posts
2009-02-04 13:24:02 -05:00
return $post_id ;
2009-02-17 14:58:03 -05:00
}
2009-02-04 13:24:02 -05:00
if ( ! $post_id ) {
2009-02-17 14:58:03 -05:00
_e ( " Couldn't get post ID (creating post failed!) " );
2009-02-04 13:24:02 -05:00
echo '</li>' ;
2009-02-17 14:58:03 -05:00
return new WP_Error ( 'insert_post_failed' , __ ( 'Failed to create post.' ) );
2009-02-04 13:24:02 -05:00
}
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
// Handle all the metadata for this post
$this -> insert_postmeta ( $post_id , $post );
}
echo '</li>' ;
}
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
// Convert lj-user tags to links to that user
function translate_lj_user ( $str ) {
return preg_replace ( '|<lj\s+user\s*=\s*["\']([\w-]+)["\']>|' , '<a href="http://$1.livejournal.com/" class="lj-user">$1</a>' , $str );
}
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
function insert_postmeta ( $post_id , $post ) {
// Need the original LJ id for comments
add_post_meta ( $post_id , 'lj_itemid' , $post [ 'itemid' ] );
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
// And save the permalink on LJ in case we want to link back or something
add_post_meta ( $post_id , 'lj_permalink' , $post [ 'url' ] );
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
// Supports the following "props" from LJ, saved as lj_<prop_name> in wp_postmeta
// Adult Content - adult_content
// Location - current_coords + current_location
// Mood - current_mood (translated from current_moodid)
// Music - current_music
// Userpic - picture_keyword
foreach ( array ( 'adult_content' , 'current_coords' , 'current_location' , 'current_moodid' , 'current_music' , 'picture_keyword' ) as $prop ) {
if ( ! empty ( $post [ 'props' ][ $prop ] ) ) {
if ( 'current_moodid' == $prop ) {
$prop = 'current_mood' ;
$val = $this -> moods [ $post [ 'props' ][ 'current_moodid' ] ];
} else {
$val = $post [ 'props' ][ $prop ];
2009-02-04 12:47:50 -05:00
}
2009-02-04 13:24:02 -05:00
add_post_meta ( $post_id , 'lj_' . $prop , $val );
2005-12-28 15:24:12 -05:00
}
2009-02-04 13:24:02 -05:00
}
}
2009-03-17 22:43:45 -04:00
2009-02-10 14:34:52 -05:00
// Set up a session (authenticate) with LJ
2009-02-17 14:58:03 -05:00
function get_session () {
2009-02-04 13:24:02 -05:00
// Get a session via XMLRPC
$cookie = $this -> lj_ixr ( 'sessiongenerate' , array ( 'ver' => 1 , 'expiration' => 'short' ) );
2009-02-17 14:58:03 -05:00
if ( is_wp_error ( $cookie ) )
return new WP_Error ( 'cookie' , __ ( 'Could not get a cookie from LiveJournal. Please try again soon.' ) );
2009-02-10 14:34:52 -05:00
return new WP_Http_Cookie ( array ( 'name' => 'ljsession' , 'value' => $cookie [ 'ljsession' ] ) );
}
2009-03-17 22:43:45 -04:00
2009-02-10 14:34:52 -05:00
// Loops through and gets comment meta from LJ in batches
function download_comment_meta () {
2009-02-17 14:58:03 -05:00
$cookie = $this -> get_session ();
if ( is_wp_error ( $cookie ) )
return $cookie ;
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
// Load previous state (if any)
$this -> usermap = ( array ) get_option ( 'ljapi_usermap' );
2009-02-10 14:34:52 -05:00
$maxid = get_option ( 'ljapi_maxid' ) ? get_option ( 'ljapi_maxid' ) : 1 ;
$highest_id = get_option ( 'ljapi_highest_id' ) ? get_option ( 'ljapi_highest_id' ) : 0 ;
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
// We need to loop over the metadata request until we have it all
while ( $maxid > $highest_id ) {
// Now get the meta listing
2009-02-10 14:34:52 -05:00
$results = wp_remote_get ( $this -> comments_url . '?get=comment_meta&startid=' . ( $highest_id + 1 ),
array ( 'cookies' => array ( $cookie ), 'timeout' => 20 ) );
if ( is_wp_error ( $results ) )
return new WP_Error ( 'comment_meta' , __ ( 'Failed to retrieve comment meta information from LiveJournal. Please try again soon.' ) );
2009-03-17 22:43:45 -04:00
2009-02-10 14:34:52 -05:00
$results = wp_remote_retrieve_body ( $results );
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
// Get the maxid so we know if we have them all yet
preg_match ( '|<maxid>(\d+)</maxid>|' , $results , $matches );
2009-02-10 14:34:52 -05:00
if ( 0 == $matches [ 1 ] ) {
// No comment meta = no comments for this journal
echo '<p>' . __ ( 'You have no comments to import!' ) . '</p>' ;
update_option ( 'ljapi_highest_id' , 1 );
update_option ( 'ljapi_highest_comment_id' , 1 );
return false ; // Bail out of comment importing entirely
}
2009-02-04 13:24:02 -05:00
$maxid = ! empty ( $matches [ 1 ] ) ? $matches [ 1 ] : $maxid ;
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
// Parse comments and get highest id available
preg_match_all ( '|<comment id=\'(\d+)\'|is' , $results , $matches );
foreach ( $matches [ 1 ] as $id ) {
if ( $id > $highest_id )
$highest_id = $id ;
2006-01-05 00:35:09 -05:00
}
2009-02-04 13:24:02 -05:00
// Parse out the list of user mappings, and add it to the known list
preg_match_all ( '|<usermap id=\'(\d+)\' user=\'([^\']+)\' />|' , $results , $matches );
foreach ( $matches [ 1 ] as $count => $userid )
$this -> usermap [ $userid ] = $matches [ 2 ][ $count ]; // need this in memory for translating ids => names
2009-03-17 22:43:45 -04:00
2009-02-10 14:34:52 -05:00
wp_cache_flush ();
2009-02-04 13:24:02 -05:00
}
// endwhile - should have seen all comment meta at this point
2009-02-10 14:34:52 -05:00
update_option ( 'ljapi_usermap' , $this -> usermap );
update_option ( 'ljapi_maxid' , $maxid );
update_option ( 'ljapi_highest_id' , $highest_id );
2009-03-17 22:43:45 -04:00
2009-02-17 14:58:03 -05:00
echo '<p>' . __ ( ' Comment metadata downloaded successfully, proceeding with comment bodies...' ) . '</p>' ;
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
return true ;
2005-12-28 15:24:12 -05:00
}
2009-03-17 22:43:45 -04:00
2009-02-10 14:34:52 -05:00
// Downloads actual comment bodies from LJ
// Inserts them all directly to the DB, with additional info stored in "spare" fields
function download_comment_bodies () {
global $wpdb ;
2009-02-17 14:58:03 -05:00
$cookie = $this -> get_session ();
if ( is_wp_error ( $cookie ) )
return $cookie ;
2009-03-17 22:43:45 -04:00
2009-02-10 14:34:52 -05:00
// Load previous state (if any)
$this -> usermap = ( array ) get_option ( 'ljapi_usermap' );
$maxid = get_option ( 'ljapi_maxid' ) ? ( int ) get_option ( 'ljapi_maxid' ) : 1 ;
$highest_id = ( int ) get_option ( 'ljapi_highest_comment_id' );
$loop = 0 ;
while ( $maxid > $highest_id && $loop < 5 ) { // We do 5 loops per call to avoid memory limits
$loop ++ ;
2009-03-17 22:43:45 -04:00
2009-02-10 14:34:52 -05:00
// Get a batch of comments, using the highest_id we've already got as a starting point
$results = wp_remote_get ( $this -> comments_url . '?get=comment_body&startid=' . ( $highest_id + 1 ),
array ( 'cookies' => array ( $cookie ), 'timeout' => 20 ) );
if ( is_wp_error ( $results ) )
return new WP_Error ( 'comment_bodies' , __ ( 'Failed to retrieve comment bodies from LiveJournal. Please try again soon.' ) );
2009-03-17 22:43:45 -04:00
2009-02-10 14:34:52 -05:00
$results = wp_remote_retrieve_body ( $results );
2009-03-17 22:43:45 -04:00
2009-02-10 14:34:52 -05:00
// Parse out each comment and insert directly
preg_match_all ( '|<comment id=\'(\d+)\'.*</comment>|iUs' , $results , $matches );
for ( $c = 0 ; $c < count ( $matches [ 0 ] ); $c ++ ) {
// Keep track of highest id seen
if ( $matches [ 1 ][ $c ] > $highest_id ) {
$highest_id = $matches [ 1 ][ $c ];
update_option ( 'ljapi_highest_comment_id' , $highest_id );
}
2009-03-17 22:43:45 -04:00
2009-02-10 14:34:52 -05:00
$comment = $matches [ 0 ][ $c ];
// Filter out any captured, deleted comments (nothing useful to import)
$comment = preg_replace ( '|<comment id=\'\d+\' jitemid=\'\d+\' posterid=\'\d+\' state=\'D\'[^/]*/>|is' , '' , $comment );
// Parse this comment into an array and insert
$comment = $this -> parse_comment ( $comment );
$id = wp_insert_comment ( $comment );
// Clear cache
clean_comment_cache ( $id );
2009-02-04 13:24:02 -05:00
}
2009-03-17 22:43:45 -04:00
2009-02-10 14:34:52 -05:00
// Clear cache to preseve memory
wp_cache_flush ();
2009-02-04 13:24:02 -05:00
}
2009-02-10 14:34:52 -05:00
// endwhile - all comments downloaded and ready for bulk processing
2009-03-17 22:43:45 -04:00
2009-02-10 14:34:52 -05:00
// Counter just used to show progress to user
update_option ( 'ljapi_comment_batch' , ( ( int ) get_option ( 'ljapi_comment_batch' ) + 1 ) );
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
return true ;
}
2009-03-17 22:43:45 -04:00
2009-02-10 14:34:52 -05:00
// Takes a block of XML and parses out all the elements of the comment
2009-02-04 13:24:02 -05:00
function parse_comment ( $comment ) {
global $wpdb ;
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
// Get the top-level attributes
preg_match ( '|<comment([^>]+)>|i' , $comment , $attribs );
preg_match ( '| id=\'(\d+)\'|i' , $attribs [ 1 ], $matches );
$lj_comment_ID = $matches [ 1 ];
preg_match ( '| jitemid=\'(\d+)\'|i' , $attribs [ 1 ], $matches );
$lj_comment_post_ID = $matches [ 1 ];
preg_match ( '| posterid=\'(\d+)\'|i' , $attribs [ 1 ], $matches );
2009-02-10 14:34:52 -05:00
$comment_author_ID = isset ( $matches [ 1 ] ) ? $matches [ 1 ] : 0 ;
preg_match ( '| parentid=\'(\d+)\'|i' , $attribs [ 1 ], $matches ); // optional
$lj_comment_parent = isset ( $matches [ 1 ] ) ? $matches [ 1 ] : 0 ;
preg_match ( '| state=\'([SDFA])\'|i' , $attribs [ 1 ], $matches ); // optional
$lj_comment_state = isset ( $matches [ 1 ] ) ? $matches [ 1 ] : 'A' ;
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
// Clean up "subject" - this will become the first line of the comment in WP
preg_match ( '|<subject>(.*)</subject>|is' , $comment , $matches );
2009-02-10 14:34:52 -05:00
if ( isset ( $matches [ 1 ] ) ) {
$comment_subject = $wpdb -> escape ( trim ( $matches [ 1 ] ) );
if ( 'Re:' == $comment_subject )
$comment_subject = '' ;
}
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
// Get the body and HTMLize it
preg_match ( '|<body>(.*)</body>|is' , $comment , $matches );
$comment_content = ! empty ( $comment_subject ) ? $comment_subject . " \n \n " . $matches [ 1 ] : $matches [ 1 ];
$comment_content = html_entity_decode ( $comment_content );
$comment_content = str_replace ( ''' , " ' " , $comment_content );
$comment_content = wpautop ( $comment_content );
$comment_content = str_replace ( '<br>' , '<br />' , $comment_content );
$comment_content = str_replace ( '<hr>' , '<hr />' , $comment_content );
$comment_content = preg_replace_callback ( '|<(/?[A-Z]+)|' , create_function ( '$match' , 'return "<" . strtolower( $match[1] );' ), $comment_content );
$comment_content = $wpdb -> escape ( trim ( $comment_content ) );
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
// Get and convert the date
preg_match ( '|<date>(.*)</date>|i' , $comment , $matches );
$comment_date = trim ( str_replace ( array ( 'T' , 'Z' ), ' ' , $matches [ 1 ] ) );
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
// Grab IP if available
2009-02-10 14:34:52 -05:00
preg_match ( '|<property name=\'poster_ip\'>(.*)</property>|i' , $comment , $matches ); // optional
$comment_author_IP = isset ( $matches [ 1 ] ) ? $matches [ 1 ] : '' ;
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
// Try to get something useful for the comment author, especially if it was "my" comment
2009-02-10 14:34:52 -05:00
$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 ];
2009-02-04 13:24:02 -05:00
if ( get_option ( 'ljapi_username' ) == $author ) {
$user = wp_get_current_user ();
$user_id = $user -> ID ;
$author = $user -> display_name ;
$url = trailingslashit ( get_option ( 'home' ) );
} else {
$user_id = 0 ;
2009-03-17 22:43:45 -04:00
$url = ( __ ( 'Anonymous' ) == $author ) ? '' : 'http://' . $author . '.livejournal.com/' ;
2009-02-04 13:24:02 -05:00
}
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
// Send back the array of details
return array ( 'lj_comment_ID' => $lj_comment_ID ,
'lj_comment_post_ID' => $lj_comment_post_ID ,
'lj_comment_parent' => ( ! empty ( $lj_comment_parent ) ? $lj_comment_parent : 0 ),
'lj_comment_state' => $lj_comment_state ,
'comment_post_ID' => $this -> get_wp_post_ID ( $lj_comment_post_ID ),
'comment_author' => $author ,
'comment_author_url' => $url ,
2009-02-10 14:34:52 -05:00
'comment_author_email' => '' ,
2009-02-04 13:24:02 -05:00
'comment_content' => $comment_content ,
'comment_date' => $comment_date ,
'comment_author_IP' => ( ! empty ( $comment_author_IP ) ? $comment_author_IP : '' ),
'comment_approved' => ( in_array ( $lj_comment_state , array ( 'A' , 'F' ) ) ? 1 : 0 ),
2009-02-10 14:34:52 -05:00
'comment_karma' => $lj_comment_ID , // Need this and next value until rethreading is done
'comment_agent' => $lj_comment_parent ,
'comment_type' => 'livejournal' , // Custom type, so we can find it later for processing
'user_ID' => $user_id
);
2009-02-04 13:24:02 -05:00
}
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
// Gets the post_ID that a LJ post has been saved as within WP
function get_wp_post_ID ( $post ) {
global $wpdb ;
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
if ( empty ( $this -> postmap [ $post ] ) )
2009-02-10 14:34:52 -05:00
$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 ) );
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
return $this -> postmap [ $post ];
}
2009-03-17 22:43:45 -04:00
2009-02-10 14:34:52 -05:00
// Gets the comment_ID that a LJ comment has been saved as within WP
function get_wp_comment_ID ( $comment ) {
global $wpdb ;
if ( empty ( $this -> commentmap [ $comment ] ) )
$this -> commentmap [ $comment ] = $wpdb -> get_var ( $wpdb -> prepare ( " SELECT comment_ID FROM $wpdb->comments WHERE comment_karma = %d " , $comment ) );
return $this -> commentmap [ $comment ];
2009-02-04 13:24:02 -05:00
}
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
function lj_ixr () {
if ( $challenge = $this -> ixr -> query ( 'LJ.XMLRPC.getchallenge' ) ) {
$challenge = $this -> ixr -> getResponse ();
}
if ( isset ( $challenge [ 'challenge' ] ) ) {
$params = array ( 'username' => $this -> username ,
'auth_method' => 'challenge' ,
'auth_challenge' => $challenge [ 'challenge' ],
'auth_response' => md5 ( $challenge [ 'challenge' ] . md5 ( $this -> password ) ) );
} else {
2009-02-17 14:58:03 -05:00
return new WP_Error ( 'IXR' , __ ( 'LiveJournal is not responding to authentication requests. Please wait a while and then try again.' ) );
2009-02-04 13:24:02 -05:00
}
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
$args = func_get_args ();
$method = array_shift ( $args );
if ( isset ( $args [ 0 ] ) )
$params = array_merge ( $params , $args [ 0 ] );
if ( $this -> ixr -> query ( 'LJ.XMLRPC.' . $method , $params ) ) {
return $this -> ixr -> getResponse ();
} else {
2009-02-17 14:58:03 -05:00
return new WP_Error ( 'IXR' , __ ( 'XML-RPC Request Failed -- ' ) . $this -> ixr -> getErrorCode () . ': ' . $this -> ixr -> getErrorMessage () );
2009-02-04 13:24:02 -05:00
}
}
2009-03-17 22:43:45 -04:00
2005-12-28 15:24:12 -05:00
function dispatch () {
2009-02-04 13:24:02 -05:00
if ( empty ( $_REQUEST [ 'step' ] ) )
2005-12-28 15:24:12 -05:00
$step = 0 ;
else
2009-02-04 13:24:02 -05:00
$step = ( int ) $_REQUEST [ 'step' ];
2005-12-28 15:24:12 -05:00
$this -> header ();
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
switch ( $step ) {
case - 1 :
$this -> cleanup ();
// Intentional no break
2005-12-28 15:24:12 -05:00
case 0 :
$this -> greet ();
break ;
case 1 :
2009-02-10 14:34:52 -05:00
case 2 :
2009-02-04 13:24:02 -05:00
case 3 :
check_admin_referer ( 'lj-api-import' );
$result = $this -> { 'step' . $step }();
2009-02-17 14:58:03 -05:00
if ( is_wp_error ( $result ) ) {
$this -> throw_error ( $result , $step );
}
2005-12-28 15:24:12 -05:00
break ;
}
2006-02-12 02:53:23 -05:00
2005-12-28 15:24:12 -05:00
$this -> footer ();
}
2009-02-17 14:58:03 -05:00
// Technically the first half of step 1, this is separated to allow for AJAX
// calls. Sets up some variables and options and confirms authentication.
function setup () {
global $verified ;
2009-02-04 13:24:02 -05:00
// Get details from form or from DB
if ( ! empty ( $_POST [ 'lj_username' ] ) && ! empty ( $_POST [ 'lj_password' ] ) ) {
// Store details for later
$this -> username = $_POST [ 'lj_username' ];
$this -> password = $_POST [ 'lj_password' ];
update_option ( 'ljapi_username' , $this -> username );
update_option ( 'ljapi_password' , $this -> password );
} else {
$this -> username = get_option ( 'ljapi_username' );
$this -> password = get_option ( 'ljapi_password' );
}
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
// This is the password to set on protected posts
if ( ! empty ( $_POST [ 'protected_password' ] ) ) {
$this -> protected_password = $_POST [ 'protected_password' ];
update_option ( 'ljapi_protected_password' , $this -> protected_password );
} else {
$this -> protected_password = get_option ( 'ljapi_protected_password' );
}
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
// Login to confirm the details are correct
if ( empty ( $this -> username ) || empty ( $this -> password ) ) {
?>
< p >< ? php _e ( 'Please enter your LiveJournal username <em>and</em> password so we can download your posts and comments.' ) ?> </p>
2009-03-17 22:46:32 -04:00
< p >< a href = " <?php echo clean_url( $_SERVER['PHP_SELF'] . '?import=livejournal&step=-1&_wpnonce=' . wp_create_nonce( 'lj-api-import' ) . '&_wp_http_referer=' . attribute_escape( str_replace( '&step=1', '', $_SERVER['REQUEST_URI'] ) ) ) ?> " >< ? php _e ( 'Start again' ) ?> </a></p>
2009-02-04 13:24:02 -05:00
< ? php
2009-02-17 14:58:03 -05:00
return false ;
2009-02-04 13:24:02 -05:00
}
2009-02-17 14:58:03 -05:00
$verified = $this -> lj_ixr ( 'login' );
if ( is_wp_error ( $verified ) ) {
2009-02-04 13:24:02 -05:00
if ( 100 == $this -> ixr -> getErrorCode () || 101 == $this -> ixr -> getErrorCode () ) {
2009-02-10 14:34:52 -05:00
delete_option ( 'ljapi_username' );
delete_option ( 'ljapi_password' );
2009-02-17 14:58:03 -05:00
delete_option ( 'ljapi_protected_password' );
2009-02-04 13:24:02 -05:00
?>
< p >< ? php _e ( 'Logging in to LiveJournal failed. Check your username and password and try again.' ) ?> </p>
2009-03-17 22:46:32 -04:00
< p >< a href = " <?php echo clean_url( $_SERVER['PHP_SELF'] . '?import=livejournal&step=-1&_wpnonce=' . wp_create_nonce( 'lj-api-import' ) . '&_wp_http_referer=' . attribute_escape( str_replace( '&step=1', '', $_SERVER['REQUEST_URI'] ) ) ) ?> " >< ? php _e ( 'Start again' ) ?> </a></p>
2009-02-04 13:24:02 -05:00
< ? php
2009-02-17 14:58:03 -05:00
return false ;
2009-02-04 13:24:02 -05:00
} else {
2009-02-17 14:58:03 -05:00
return $verified ;
2009-02-04 13:24:02 -05:00
}
2009-02-17 14:58:03 -05:00
} else {
update_option ( 'ljapi_verified' , 'yes' );
2009-02-04 13:24:02 -05:00
}
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
// Set up some options to avoid them autoloading (these ones get big)
2009-02-10 14:34:52 -05:00
add_option ( 'ljapi_sync_item_times' , '' , '' , 'no' );
add_option ( 'ljapi_usermap' , '' , '' , 'no' );
update_option ( 'ljapi_comment_batch' , 0 );
2009-03-17 22:43:45 -04:00
2009-02-17 14:58:03 -05:00
return true ;
}
// Check form inputs and start importing posts
function step1 () {
global $verified ;
set_time_limit ( 0 );
update_option ( 'ljapi_step' , 1 );
if ( ! $this -> ixr ) $this -> ixr = new IXR_Client ( $this -> ixr_url , false , 80 , 30 );
if ( empty ( $_POST [ 'login' ] ) ) {
// We're looping -- load some details from DB
$this -> username = get_option ( 'ljapi_username' );
$this -> password = get_option ( 'ljapi_password' );
$this -> protected_password = get_option ( 'ljapi_protected_password' );
} else {
// First run (non-AJAX)
$setup = $this -> setup ();
if ( ! $setup ) {
return false ;
} else if ( is_wp_error ( $setup ) ) {
$this -> throw_error ( $setup , 1 );
return false ;
}
}
2009-03-17 22:43:45 -04:00
2009-02-17 14:58:03 -05:00
echo '<div id="ljapi-status">' ;
2009-02-04 13:24:02 -05:00
echo '<h3>' . __ ( 'Importing Posts' ) . '</h3>' ;
2009-02-17 14:58:03 -05:00
echo '<p>' . __ ( " We're downloading and importing your LiveJournal posts... " ) . '</p>' ;
if ( get_option ( 'ljapi_post_batch' ) && count ( get_option ( 'ljapi_sync_item_times' ) ) ) {
$batch = count ( get_option ( 'ljapi_sync_item_times' ) );
$batch = $count > 300 ? ceil ( $batch / 300 ) : 1 ;
echo '<p><strong>' . sprintf ( __ ( 'Imported post batch %d of <strong>approximately</strong> %d' ), ( get_option ( 'ljapi_post_batch' ) + 1 ), $batch ) . '</strong></p>' ;
}
2009-02-04 13:24:02 -05:00
ob_flush (); flush ();
2009-03-17 22:43:45 -04:00
2009-02-17 14:58:03 -05:00
if ( ! get_option ( 'ljapi_lastsync' ) || '1900-01-01 00:00:00' == get_option ( 'ljapi_lastsync' ) ) {
// We haven't downloaded meta yet, so do that first
$result = $this -> download_post_meta ();
if ( is_wp_error ( $result ) ) {
$this -> throw_error ( $result , 1 );
return false ;
}
}
// Download a batch of actual posts
$result = $this -> download_post_bodies ();
2009-02-04 13:24:02 -05:00
if ( is_wp_error ( $result ) ) {
if ( 406 == $this -> ixr -> getErrorCode () ) {
?>
< p >< strong >< ? php _e ( 'Uh oh – LiveJournal has disconnected us because we made too many requests to their servers too quickly.' ) ?> </strong></p>
< 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>
< ? php
2009-02-17 14:58:03 -05:00
echo $this -> next_step ( 1 , __ ( 'Try Again' ) );
return false ;
2009-02-04 13:24:02 -05:00
} else {
2009-02-17 14:58:03 -05:00
$this -> throw_error ( $result , 1 );
return false ;
2009-02-04 13:24:02 -05:00
}
}
2009-02-17 14:58:03 -05:00
if ( get_option ( 'ljapi_last_sync_count' ) > 0 ) {
?>
< form action = " admin.php?import=livejournal " method = " post " id = " ljapi-auto-repost " >
< ? php wp_nonce_field ( 'lj-api-import' ) ?>
< input type = " hidden " name = " step " id = " step " value = " 1 " />
2009-02-25 13:56:58 -05:00
< p >< input type = " submit " class = " button-primary " value = " <?php echo attribute_escape( __( 'Import the next batch' ) ) ?> " /> < span id = " auto-message " ></ span ></ p >
2009-02-17 14:58:03 -05:00
</ form >
< ? php $this -> auto_ajax ( 'ljapi-auto-repost' , 'auto-message' , 0 ); ?>
< ? php
} else {
echo '<p>' . __ ( " Your posts have all been imported, but wait - there's more! Now we need to download & import your comments. " ) . '</p>' ;
echo $this -> next_step ( 2 , __ ( 'Download my comments »' ) );
$this -> auto_submit ();
}
echo '</div>' ;
2009-02-04 13:24:02 -05:00
}
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
// Download comments to local XML
function step2 () {
set_time_limit ( 0 );
update_option ( 'ljapi_step' , 2 );
$this -> username = get_option ( 'ljapi_username' );
$this -> password = get_option ( 'ljapi_password' );
2009-02-17 14:58:03 -05:00
$this -> ixr = new IXR_Client ( $this -> ixr_url , false , 80 , 30 );
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
echo '<div id="ljapi-status">' ;
2009-02-10 14:34:52 -05:00
echo '<h3>' . __ ( 'Downloading Comments' ) . '</h3>' ;
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>' ;
2009-02-04 13:24:02 -05:00
ob_flush (); flush ();
2009-03-17 22:43:45 -04:00
2009-02-10 14:34:52 -05:00
if ( ! get_option ( 'ljapi_usermap' ) ) {
// We haven't downloaded meta yet, so do that first
$result = $this -> download_comment_meta ();
2009-02-17 14:58:03 -05:00
if ( is_wp_error ( $result ) ) {
$this -> throw_error ( $result , 2 );
return false ;
}
2009-02-04 13:24:02 -05:00
}
2009-02-10 14:34:52 -05:00
// Download a batch of actual comments
$result = $this -> download_comment_bodies ();
2009-02-17 14:58:03 -05:00
if ( is_wp_error ( $result ) ) {
$this -> throw_error ( $result , 2 );
return false ;
}
2009-02-10 14:34:52 -05:00
$maxid = get_option ( 'ljapi_maxid' ) ? ( int ) get_option ( 'ljapi_maxid' ) : 1 ;
$highest_id = ( int ) get_option ( 'ljapi_highest_comment_id' );
if ( $maxid > $highest_id ) {
2009-02-17 14:58:03 -05:00
$batch = $maxid > 5000 ? ceil ( $maxid / 5000 ) : 1 ;
2009-02-10 14:34:52 -05:00
?>
< form action = " admin.php?import=livejournal " method = " post " id = " ljapi-auto-repost " >
2009-02-17 14:58:03 -05:00
< p >< strong >< ? php printf ( __ ( 'Imported comment batch %d of <strong>approximately</strong> %d' ), get_option ( 'ljapi_comment_batch' ), $batch ) ?> </strong></p>
2009-02-10 14:34:52 -05:00
< ? php wp_nonce_field ( 'lj-api-import' ) ?>
< input type = " hidden " name = " step " id = " step " value = " 2 " />
2009-02-25 13:56:58 -05:00
< p >< input type = " submit " class = " button-primary " value = " <?php echo attribute_escape( __( 'Import the next batch' ) ) ?> " /> < span id = " auto-message " ></ span ></ p >
2009-02-10 14:34:52 -05:00
</ form >
< ? php $this -> auto_ajax ( 'ljapi-auto-repost' , 'auto-message' , 0 ); ?>
< ? php
2009-02-04 13:24:02 -05:00
} else {
2009-02-10 14:34:52 -05:00
echo '<p>' . __ ( 'Your comments have all been imported now, but we still need to rebuild your conversation threads.' ) . '</p>' ;
echo $this -> next_step ( 3 , __ ( 'Rebuild my comment threads »' ) );
2009-02-04 13:24:02 -05:00
$this -> auto_submit ();
}
echo '</div>' ;
}
2009-03-17 22:43:45 -04:00
2009-02-10 14:34:52 -05:00
// Re-thread comments already in the DB
function step3 () {
global $wpdb ;
2009-02-04 13:24:02 -05:00
set_time_limit ( 0 );
2009-02-10 14:34:52 -05:00
update_option ( 'ljapi_step' , 3 );
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
echo '<div id="ljapi-status">' ;
echo '<h3>' . __ ( 'Threading Comments' ) . '</h3>' ;
2009-02-10 14:34:52 -05:00
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>' ;
2009-02-04 13:24:02 -05:00
ob_flush (); flush ();
2009-03-17 22:43:45 -04:00
2009-02-10 14:34:52 -05:00
// Only bother adding indexes if they have over 5000 comments (arbitrary number)
$imported_comments = $wpdb -> get_var ( " SELECT COUNT(*) FROM { $wpdb -> comments } WHERE comment_type = 'livejournal' " );
$added_indices = false ;
if ( 5000 < $imported_comments ) {
include_once ( ABSPATH . 'wp-admin/includes/upgrade.php' );
$added_indices = true ;
add_clean_index ( $wpdb -> comments , 'comment_type' );
add_clean_index ( $wpdb -> comments , 'comment_karma' );
add_clean_index ( $wpdb -> comments , 'comment_agent' );
2009-02-04 13:24:02 -05:00
}
2009-03-17 22:43:45 -04:00
2009-02-10 14:34:52 -05:00
// Get LJ comments, which haven't been threaded yet, 5000 at a time and thread them
while ( $comments = $wpdb -> get_results ( " SELECT comment_ID, comment_agent FROM { $wpdb -> comments } WHERE comment_type = 'livejournal' AND comment_agent != '0' LIMIT 5000 " , OBJECT ) ) {
foreach ( $comments as $comment ) {
2009-03-17 22:43:45 -04:00
$wpdb -> update ( $wpdb -> comments ,
array ( 'comment_parent' => $this -> get_wp_comment_ID ( $comment -> comment_agent ), 'comment_type' => 'livejournal-done' ),
2009-02-10 14:34:52 -05:00
array ( 'comment_ID' => $comment -> comment_ID ) );
}
wp_cache_flush ();
$wpdb -> flush ();
2009-02-04 13:24:02 -05:00
}
2009-03-17 22:43:45 -04:00
2009-02-10 14:34:52 -05:00
// Revert the comments table back to normal and optimize it to reclaim space
if ( $added_indices ) {
drop_index ( $wpdb -> comments , 'comment_type' );
drop_index ( $wpdb -> comments , 'comment_karma' );
drop_index ( $wpdb -> comments , 'comment_agent' );
$wpdb -> query ( " OPTIMIZE TABLE { $wpdb -> comments } " );
2009-02-04 13:24:02 -05:00
}
2009-03-17 22:43:45 -04:00
2009-02-10 14:34:52 -05:00
// Clean up database and we're out
$this -> cleanup ();
do_action ( 'import_done' , 'livejournal' );
if ( $imported_comments > 1 )
2009-02-17 14:58:03 -05:00
echo '<p>' . sprintf ( __ ( " Successfully re-threaded %s comments. " ), number_format ( $imported_comments ) ) . '</p>' ;
2009-02-10 14:34:52 -05:00
echo '<h3>' ;
printf ( __ ( 'All done. <a href="%s">Have fun!</a>' ), get_option ( 'home' ) );
echo '</h3>' ;
2009-02-04 13:24:02 -05:00
echo '</div>' ;
}
2009-03-17 22:43:45 -04:00
2009-02-17 14:58:03 -05:00
// Output an error message with a button to try again.
function throw_error ( $error , $step ) {
echo '<p><strong>' . $error -> get_error_message () . '</strong></p>' ;
echo $this -> next_step ( $step , __ ( 'Try Again' ) );
}
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
// Returns the HTML for a link to the next page
function next_step ( $next_step , $label , $id = 'ljapi-next-form' ) {
$str = '<form action="admin.php?import=livejournal" method="post" id="' . $id . '">' ;
$str .= wp_nonce_field ( 'lj-api-import' , '_wpnonce' , true , false );
$str .= wp_referer_field ( false );
$str .= '<input type="hidden" name="step" id="step" value="' . $next_step . '" />' ;
$str .= '<p><input type="submit" class="button-primary" value="' . attribute_escape ( $label ) . '" /> <span id="auto-message"></span></p>' ;
$str .= '</form>' ;
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
return $str ;
}
2009-03-17 22:43:45 -04:00
2009-02-10 14:34:52 -05:00
// Automatically submit the specified form after $seconds
// Include a friendly countdown in the element with id=$msg
function auto_submit ( $id = 'ljapi-next-form' , $msg = 'auto-message' , $seconds = 10 ) {
2009-02-04 13:24:02 -05:00
?> <script type="text/javascript">
next_counter = < ? php echo $seconds ?> ;
jQuery ( document ) . ready ( function (){
ljapi_msg ();
});
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
function ljapi_msg () {
str = '<?php _e( "Continuing in %d" ) ?>' ;
jQuery ( '#<?php echo $msg ?>' ) . text ( str . replace ( /% d / , next_counter ) );
if ( next_counter <= 0 ) {
if ( jQuery ( '#<?php echo $id ?>' ) . length ) {
jQuery ( " #<?php echo $id ?> input[type='submit'] " ) . hide ();
2009-02-10 14:34:52 -05:00
str = '<?php _e( "Continuing" ) ?> <img src="images/loading-publish.gif" alt="" id="processing" align="top" />' ;
2009-02-04 13:24:02 -05:00
jQuery ( '#<?php echo $msg ?>' ) . html ( str );
2009-02-10 14:34:52 -05:00
jQuery ( '#<?php echo $id ?>' ) . submit ();
2009-02-04 13:24:02 -05:00
return ;
}
}
next_counter = next_counter - 1 ;
setTimeout ( 'ljapi_msg()' , 1000 );
}
</ script >< ? php
}
2009-03-17 22:43:45 -04:00
2009-02-10 14:34:52 -05:00
// Automatically submit the form with #id to continue the process
// Hide any submit buttons to avoid people clicking them
// Display a countdown in the element indicated by $msg for "Continuing in x"
function auto_ajax ( $id = 'ljapi-next-form' , $msg = 'auto-message' , $seconds = 5 ) {
2009-02-04 13:24:02 -05:00
?> <script type="text/javascript">
next_counter = < ? php echo $seconds ?> ;
jQuery ( document ) . ready ( function (){
ljapi_msg ();
});
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
function ljapi_msg () {
str = '<?php _e( "Continuing in %d" ) ?>' ;
jQuery ( '#<?php echo $msg ?>' ) . text ( str . replace ( /% d / , next_counter ) );
if ( next_counter <= 0 ) {
if ( jQuery ( '#<?php echo $id ?>' ) . length ) {
jQuery ( " #<?php echo $id ?> input[type='submit'] " ) . hide ();
2009-02-10 14:34:52 -05:00
jQuery . ajaxSetup ({ 'timeout' : 3600000 });
str = '<?php _e( "Processing next batch." ) ?> <img src="images/loading-publish.gif" alt="" id="processing" align="top" />' ;
2009-02-04 13:24:02 -05:00
jQuery ( '#<?php echo $msg ?>' ) . html ( str );
2009-02-10 14:34:52 -05:00
jQuery ( '#ljapi-status' ) . load ( ajaxurl , { 'action' : 'lj-importer' ,
'step' : jQuery ( '#step' ) . val (),
'_wpnonce' : '<?php echo wp_create_nonce( ' lj - api - import ' ) ?>' ,
'_wp_http_referer' : '<?php echo $_SERVER[' REQUEST_URI '] ?>' });
2009-02-04 13:24:02 -05:00
return ;
}
}
next_counter = next_counter - 1 ;
setTimeout ( 'ljapi_msg()' , 1000 );
}
</ script >< ? php
}
2009-02-10 14:34:52 -05:00
// Remove all options used during import process and
// set wp_comments entries back to "normal" values
2009-02-04 13:24:02 -05:00
function cleanup () {
2009-02-10 14:34:52 -05:00
global $wpdb ;
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
delete_option ( 'ljapi_username' );
delete_option ( 'ljapi_password' );
delete_option ( 'ljapi_protected_password' );
2009-02-17 14:58:03 -05:00
delete_option ( 'ljapi_verified' );
2009-02-04 13:24:02 -05:00
delete_option ( 'ljapi_total' );
delete_option ( 'ljapi_count' );
delete_option ( 'ljapi_lastsync' );
delete_option ( 'ljapi_last_sync_count' );
delete_option ( 'ljapi_sync_item_times' );
delete_option ( 'ljapi_lastsync_posts' );
2009-02-17 14:58:03 -05:00
delete_option ( 'ljapi_post_batch' );
2009-02-04 13:24:02 -05:00
delete_option ( 'ljapi_imported_count' );
delete_option ( 'ljapi_maxid' );
delete_option ( 'ljapi_usermap' );
delete_option ( 'ljapi_highest_id' );
delete_option ( 'ljapi_highest_comment_id' );
2009-02-10 14:34:52 -05:00
delete_option ( 'ljapi_comment_batch' );
2009-02-04 13:24:02 -05:00
delete_option ( 'ljapi_step' );
2009-03-17 22:43:45 -04:00
$wpdb -> update ( $wpdb -> comments ,
array ( 'comment_karma' => 0 , 'comment_agent' => 'WP LJ Importer' , 'comment_type' => '' ),
2009-02-10 14:34:52 -05:00
array ( 'comment_type' => 'livejournal-done' ) );
2009-03-17 22:43:45 -04:00
$wpdb -> update ( $wpdb -> comments ,
array ( 'comment_karma' => 0 , 'comment_agent' => 'WP LJ Importer' , 'comment_type' => '' ),
2009-02-10 14:34:52 -05:00
array ( 'comment_type' => 'livejournal' ) );
2009-02-04 13:24:02 -05:00
}
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
function LJ_API_Import () {
$this -> __construct ();
}
2009-03-17 22:43:45 -04:00
2009-02-04 13:24:02 -05:00
function __construct () {
// Nothing
2005-12-28 15:24:12 -05:00
}
}
2009-02-04 13:24:02 -05:00
$lj_api_import = new LJ_API_Import ();
2005-12-28 15:24:12 -05:00
2009-02-04 13:24:02 -05:00
register_importer ( 'livejournal' , __ ( 'LiveJournal' ), __ ( 'Import posts from LiveJournal using their API.' ), array ( $lj_api_import , 'dispatch' ) );
2009-02-25 13:56:58 -05:00
?>