[ Index ]

PHP Cross Reference of Wordpress 2.9.1

title

Body

[close]

/wp-admin/import/ -> livejournal.php (source)

   1  <?php
   2  
   3  /**
   4   * LiveJournal API Importer
   5   *
   6   * @package WordPress
   7   * @subpackage Importer
   8   */
   9  
  10  // XML-RPC library for communicating with LiveJournal API
  11  require_once ( ABSPATH . WPINC . '/class-IXR.php' );
  12  
  13  /**
  14   * LiveJournal API Importer class
  15   *
  16   * Imports your LiveJournal contents into WordPress using the LJ API
  17   *
  18   * @since 2.8
  19   */
  20  class LJ_API_Import {
  21  
  22      var $comments_url = 'http://www.livejournal.com/export_comments.bml';
  23      var $ixr_url      = 'http://www.livejournal.com/interface/xmlrpc';
  24      var $ixr;
  25      var $username;
  26      var $password;
  27      var $comment_meta;
  28      var $comments;
  29      var $usermap;
  30      var $postmap;
  31      var $commentmap;
  32      var $pointers = array();
  33  
  34      // This list taken from LJ, they don't appear to have an API for it
  35      var $moods = array( '1' => 'aggravated',
  36                          '10' => 'discontent',
  37                          '100' => 'rushed',
  38                          '101' => 'contemplative',
  39                          '102' => 'nerdy',
  40                          '103' => 'geeky',
  41                          '104' => 'cynical',
  42                          '105' => 'quixotic',
  43                          '106' => 'crazy',
  44                          '107' => 'creative',
  45                          '108' => 'artistic',
  46                          '109' => 'pleased',
  47                          '11' => 'energetic',
  48                          '110' => 'bitchy',
  49                          '111' => 'guilty',
  50                          '112' => 'irritated',
  51                          '113' => 'blank',
  52                          '114' => 'apathetic',
  53                          '115' => 'dorky',
  54                          '116' => 'impressed',
  55                          '117' => 'naughty',
  56                          '118' => 'predatory',
  57                          '119' => 'dirty',
  58                          '12' => 'enraged',
  59                          '120' => 'giddy',
  60                          '121' => 'surprised',
  61                          '122' => 'shocked',
  62                          '123' => 'rejected',
  63                          '124' => 'numb',
  64                          '125' => 'cheerful',
  65                          '126' => 'good',
  66                          '127' => 'distressed',
  67                          '128' => 'intimidated',
  68                          '129' => 'crushed',
  69                          '13' => 'enthralled',
  70                          '130' => 'devious',
  71                          '131' => 'thankful',
  72                          '132' => 'grateful',
  73                          '133' => 'jealous',
  74                          '134' => 'nervous',
  75                          '14' => 'exhausted',
  76                          '15' => 'happy',
  77                          '16' => 'high',
  78                          '17' => 'horny',
  79                          '18' => 'hungry',
  80                          '19' => 'infuriated',
  81                          '2' => 'angry',
  82                          '20' => 'irate',
  83                          '21' => 'jubilant',
  84                          '22' => 'lonely',
  85                          '23' => 'moody',
  86                          '24' => 'pissed off',
  87                          '25' => 'sad',
  88                          '26' => 'satisfied',
  89                          '27' => 'sore',
  90                          '28' => 'stressed',
  91                          '29' => 'thirsty',
  92                          '3' => 'annoyed',
  93                          '30' => 'thoughtful',
  94                          '31' => 'tired',
  95                          '32' => 'touched',
  96                          '33' => 'lazy',
  97                          '34' => 'drunk',
  98                          '35' => 'ditzy',
  99                          '36' => 'mischievous',
 100                          '37' => 'morose',
 101                          '38' => 'gloomy',
 102                          '39' => 'melancholy',
 103                          '4' => 'anxious',
 104                          '40' => 'drained',
 105                          '41' => 'excited',
 106                          '42' => 'relieved',
 107                          '43' => 'hopeful',
 108                          '44' => 'amused',
 109                          '45' => 'determined',
 110                          '46' => 'scared',
 111                          '47' => 'frustrated',
 112                          '48' => 'indescribable',
 113                          '49' => 'sleepy',
 114                          '5' => 'bored',
 115                          '51' => 'groggy',
 116                          '52' => 'hyper',
 117                          '53' => 'relaxed',
 118                          '54' => 'restless',
 119                          '55' => 'disappointed',
 120                          '56' => 'curious',
 121                          '57' => 'mellow',
 122                          '58' => 'peaceful',
 123                          '59' => 'bouncy',
 124                          '6' => 'confused',
 125                          '60' => 'nostalgic',
 126                          '61' => 'okay',
 127                          '62' => 'rejuvenated',
 128                          '63' => 'complacent',
 129                          '64' => 'content',
 130                          '65' => 'indifferent',
 131                          '66' => 'silly',
 132                          '67' => 'flirty',
 133                          '68' => 'calm',
 134                          '69' => 'refreshed',
 135                          '7' => 'crappy',
 136                          '70' => 'optimistic',
 137                          '71' => 'pessimistic',
 138                          '72' => 'giggly',
 139                          '73' => 'pensive',
 140                          '74' => 'uncomfortable',
 141                          '75' => 'lethargic',
 142                          '76' => 'listless',
 143                          '77' => 'recumbent',
 144                          '78' => 'exanimate',
 145                          '79' => 'embarrassed',
 146                          '8' => 'cranky',
 147                          '80' => 'envious',
 148                          '81' => 'sympathetic',
 149                          '82' => 'sick',
 150                          '83' => 'hot',
 151                          '84' => 'cold',
 152                          '85' => 'worried',
 153                          '86' => 'loved',
 154                          '87' => 'awake',
 155                          '88' => 'working',
 156                          '89' => 'productive',
 157                          '9' => 'depressed',
 158                          '90' => 'accomplished',
 159                          '91' => 'busy',
 160                          '92' => 'blah',
 161                          '93' => 'full',
 162                          '95' => 'grumpy',
 163                          '96' => 'weird',
 164                          '97' => 'nauseated',
 165                          '98' => 'ecstatic',
 166                          '99' => 'chipper' );
 167  
 168  	function header() {
 169          echo '<div class="wrap">';
 170          screen_icon();
 171          echo '<h2>' . __( 'Import LiveJournal' ) . '</h2>';
 172      }
 173  
 174  	function footer() {
 175          echo '</div>';
 176      }
 177  
 178  	function greet() {
 179          ?>
 180          <div class="narrow">
 181          <form action="admin.php?import=livejournal" method="post">
 182          <?php wp_nonce_field( 'lj-api-import' ) ?>
 183          <?php if ( get_option( 'ljapi_username' ) && get_option( 'ljapi_password' ) ) : ?>
 184              <input type="hidden" name="step" value="<?php echo esc_attr( get_option( 'ljapi_step' ) ) ?>" />
 185              <p><?php _e( 'It looks like you attempted to import your LiveJournal posts previously and got interrupted.' ) ?></p>
 186              <p class="submit">
 187                  <input type="submit" class="button-primary" value="<?php esc_attr_e( 'Continue previous import' ) ?>" />
 188              </p>
 189              <p class="submitbox"><a href="<?php echo esc_url($_SERVER['PHP_SELF'] . '?import=livejournal&amp;step=-1&amp;_wpnonce=' . wp_create_nonce( 'lj-api-import' ) . '&amp;_wp_http_referer=' . esc_attr( $_SERVER['REQUEST_URI'] )) ?>" class="deletion submitdelete"><?php _e( 'Cancel &amp; start a new import' ) ?></a></p>
 190              <p>
 191          <?php else : ?>
 192              <input type="hidden" name="step" value="1" />
 193              <input type="hidden" name="login" value="true" />
 194              <p><?php _e( 'Howdy! This importer allows you to connect directly to LiveJournal and download all your entries and comments' ) ?></p>
 195              <p><?php _e( 'Enter your LiveJournal username and password below so we can connect to your account:' ) ?></p>
 196  
 197              <table class="form-table">
 198  
 199              <tr>
 200              <th scope="row"><label for="lj_username"><?php _e( 'LiveJournal Username' ) ?></label></th>
 201              <td><input type="text" name="lj_username" id="lj_username" class="regular-text" /></td>
 202              </tr>
 203  
 204              <tr>
 205              <th scope="row"><label for="lj_password"><?php _e( 'LiveJournal Password' ) ?></label></th>
 206              <td><input type="password" name="lj_password" id="lj_password" class="regular-text" /></td>
 207              </tr>
 208  
 209              </table>
 210  
 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              <p><?php _e( 'If you don&#8217;t enter a password, ALL ENTRIES from your LiveJournal will be imported as public posts in WordPress.' ) ?></p>
 213              <p><?php _e( 'Enter the password you would like to use for all protected entries here:' ) ?></p>
 214              <table class="form-table">
 215  
 216              <tr>
 217              <th scope="row"><label for="protected_password"><?php _e( 'Protected Post Password' ) ?></label></th>
 218              <td><input type="text" name="protected_password" id="protected_password" class="regular-text" /></td>
 219              </tr>
 220  
 221              </table>
 222  
 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  
 225              <p class="submit">
 226                  <input type="submit" class="button-primary" value="<?php esc_attr_e( 'Connect to LiveJournal and Import' ) ?>" />
 227              </p>
 228  
 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  
 231              <noscript>
 232                  <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>
 233              </noscript>
 234          <?php endif; ?>
 235          </form>
 236          </div>
 237          <?php
 238      }
 239  
 240  	function download_post_meta() {
 241          $total           = (int) get_option( 'ljapi_total' );
 242          $count           = (int) get_option( 'ljapi_count' );
 243          $lastsync        = get_option( 'ljapi_lastsync' );
 244          if ( !$lastsync ) {
 245              update_option( 'ljapi_lastsync', '1900-01-01 00:00:00' );
 246          }
 247          $sync_item_times = get_option( 'ljapi_sync_item_times' );
 248          if ( !is_array( $sync_item_times ) )
 249              $sync_item_times = array();
 250  
 251          do {
 252              $lastsync = date( 'Y-m-d H:i:s', strtotime( get_option( 'ljapi_lastsync' ) ) );
 253              $synclist = $this->lj_ixr( 'syncitems', array( 'ver' => 1, 'lastsync' => $lastsync ) );
 254              if ( is_wp_error( $synclist ) )
 255                  return $synclist;
 256  
 257              // Keep track of if we've downloaded everything
 258              $total = $synclist['total'];
 259              $count = $synclist['count'];
 260  
 261              foreach ( $synclist['syncitems'] as $event ) {
 262                  if ( substr( $event['item'], 0, 2 ) == 'L-' ) {
 263                      $sync_item_times[ str_replace( 'L-', '', $event['item'] ) ] = $event['time'];
 264                      if ( $event['time'] > $lastsync ) {
 265                          $lastsync = $event['time'];
 266                          update_option( 'ljapi_lastsync', $lastsync );
 267                      }
 268                  }
 269              }
 270          } while ( $total > $count );
 271          // endwhile - all post meta is cached locally
 272          unset( $synclist );
 273          update_option( 'ljapi_sync_item_times', $sync_item_times );
 274          update_option( 'ljapi_total', $total );
 275          update_option( 'ljapi_count', $count );
 276  
 277          echo '<p>' . __( 'Post metadata has been downloaded, proceeding with posts...' ) . '</p>';
 278      }
 279  
 280  	function download_post_bodies() {
 281          $imported_count  = (int) get_option( 'ljapi_imported_count' );
 282          $sync_item_times = get_option( 'ljapi_sync_item_times' );
 283          $lastsync        = get_option( 'ljapi_lastsync_posts' );
 284          if ( !$lastsync )
 285              update_option( 'ljapi_lastsync_posts', date( 'Y-m-d H:i:s', 0 ) );
 286  
 287          $count = 0;
 288          echo '<ol>';
 289          do {
 290              $lastsync = date( 'Y-m-d H:i:s', strtotime( get_option( 'ljapi_lastsync_posts' ) ) );
 291  
 292              // Get the batch of items that match up with the syncitems list
 293              $itemlist = $this->lj_ixr( 'getevents', array( 'ver' => 1,
 294                                                              'selecttype' => 'syncitems',
 295                                                              'lineendings' => 'pc',
 296                                                              'lastsync' => $lastsync ) );
 297              if ( is_wp_error( $itemlist ) )
 298                  return $itemlist;
 299  
 300              if ( $num = count( $itemlist['events'] ) ) {
 301                  for ( $e = 0; $e < count( $itemlist['events'] ); $e++ ) {
 302                      $event = $itemlist['events'][$e];
 303                      $imported_count++;
 304                      $inserted = $this->import_post( $event );
 305                      if ( is_wp_error( $inserted ) )
 306                          return $inserted;
 307                      if ( $sync_item_times[ $event['itemid'] ] > $lastsync )
 308                          $lastsync = $sync_item_times[ $event['itemid'] ];
 309                      wp_cache_flush();
 310                  }
 311                  update_option( 'ljapi_lastsync_posts',  $lastsync );
 312                  update_option( 'ljapi_imported_count',  $imported_count );
 313                  update_option( 'ljapi_last_sync_count', $num );
 314              }
 315              $count++;
 316          } while ( $num > 0 && $count < 3 ); // Doing up to 3 requests at a time to avoid memory problems
 317  
 318          // Used so that step1 knows when to stop posting back on itself
 319          update_option( 'ljapi_last_sync_count', $num );
 320  
 321          // Counter just used to show progress to user
 322          update_option( 'ljapi_post_batch', ( (int) get_option( 'ljapi_post_batch' ) + 1 ) );
 323  
 324          echo '</ol>';
 325      }
 326  
 327  	function _normalize_tag( $matches ) {
 328          return '<' . strtolower( $matches[1] );
 329      }
 330  
 331  	function import_post( $post ) {
 332          global $wpdb;
 333  
 334          // Make sure we haven't already imported this one
 335          if ( $this->get_wp_post_ID( $post['itemid'] ) )
 336              return;
 337  
 338          $user = wp_get_current_user();
 339          $post_author      = $user->ID;
 340          $post['security'] = !empty( $post['security'] ) ? $post['security'] : '';
 341          $post_status      = ( 'private' == trim( $post['security'] ) ) ? 'private' : 'publish'; // Only me
 342          $post_password    = ( 'usemask' == trim( $post['security'] ) ) ? $this->protected_password : ''; // "Friends" via password
 343  
 344          // For some reason, LJ sometimes sends a date as "2004-04-1408:38:00" (no space btwn date/time)
 345          $post_date = $post['eventtime'];
 346          if ( 18 == strlen( $post_date ) )
 347              $post_date = substr( $post_date, 0, 10 ) . ' ' . substr( $post_date, 10 );
 348  
 349          // Cleaning up and linking the title
 350          $post_title = isset( $post['subject'] ) ? trim( $post['subject'] ) : '';
 351          $post_title = $this->translate_lj_user( $post_title ); // Translate it, but then we'll strip the link
 352          $post_title = strip_tags( $post_title ); // Can't have tags in the title in WP
 353          $post_title = $wpdb->escape( $post_title );
 354  
 355          // Clean up content
 356          $post_content = $post['event'];
 357          $post_content = preg_replace_callback( '|<(/?[A-Z]+)|', array( &$this, '_normalize_tag' ), $post_content );
 358          // XHTMLize some tags
 359          $post_content = str_replace( '<br>', '<br />', $post_content );
 360          $post_content = str_replace( '<hr>', '<hr />', $post_content );
 361          // lj-cut ==>  <!--more-->
 362          $post_content = preg_replace( '|<lj-cut text="([^"]*)">|is', '<!--more $1-->', $post_content );
 363          $post_content = str_replace( array( '<lj-cut>', '</lj-cut>' ), array( '<!--more-->', '' ), $post_content );
 364          $first = strpos( $post_content, '<!--more' );
 365          $post_content = substr( $post_content, 0, $first + 1 ) . preg_replace( '|<!--more(.*)?-->|sUi', '', substr( $post_content, $first + 1 ) );
 366          // lj-user ==>  a href
 367          $post_content = $this->translate_lj_user( $post_content );
 368          //$post_content = force_balance_tags( $post_content );
 369          $post_content = $wpdb->escape( $post_content );
 370  
 371          // Handle any tags associated with the post
 372          $tags_input = !empty( $post['props']['taglist'] ) ? $post['props']['taglist'] : '';
 373  
 374          // Check if comments are closed on this post
 375          $comment_status = !empty( $post['props']['opt_nocomments'] ) ? 'closed' : 'open';
 376  
 377          echo '<li>';
 378          if ( $post_id = post_exists( $post_title, $post_content, $post_date ) ) {
 379              printf( __( 'Post <strong>%s</strong> already exists.' ), stripslashes( $post_title ) );
 380          } else {
 381              printf( __( 'Imported post <strong>%s</strong>...' ), stripslashes( $post_title ) );
 382              $postdata = compact( 'post_author', 'post_date', 'post_content', 'post_title', 'post_status', 'post_password', 'tags_input', 'comment_status' );
 383              $post_id = wp_insert_post( $postdata, true );
 384              if ( is_wp_error( $post_id ) ) {
 385                  if ( 'empty_content' == $post_id->get_error_code() )
 386                      return; // Silent skip on "empty" posts
 387                  return $post_id;
 388              }
 389              if ( !$post_id ) {
 390                  _e( 'Couldn&#8217;t get post ID (creating post failed!)' );
 391                  echo '</li>';
 392                  return new WP_Error( 'insert_post_failed', __( 'Failed to create post.' ) );
 393              }
 394  
 395              // Handle all the metadata for this post
 396              $this->insert_postmeta( $post_id, $post );
 397          }
 398          echo '</li>';
 399      }
 400  
 401      // Convert lj-user tags to links to that user
 402  	function translate_lj_user( $str ) {
 403          return preg_replace( '|<lj\s+user\s*=\s*["\']([\w-]+)["\']>|', '<a href="http://$1.livejournal.com/" class="lj-user">$1</a>', $str );
 404      }
 405  
 406  	function insert_postmeta( $post_id, $post ) {
 407          // Need the original LJ id for comments
 408          add_post_meta( $post_id, 'lj_itemid', $post['itemid'] );
 409  
 410          // And save the permalink on LJ in case we want to link back or something
 411          add_post_meta( $post_id, 'lj_permalink', $post['url'] );
 412  
 413          // Supports the following "props" from LJ, saved as lj_<prop_name> in wp_postmeta
 414          //         Adult Content - adult_content
 415          //         Location - current_coords + current_location
 416          //         Mood - current_mood (translated from current_moodid)
 417          //         Music - current_music
 418          //         Userpic - picture_keyword
 419          foreach ( array( 'adult_content', 'current_coords', 'current_location', 'current_moodid', 'current_music', 'picture_keyword' ) as $prop ) {
 420              if ( !empty( $post['props'][$prop] ) ) {
 421                  if ( 'current_moodid' == $prop ) {
 422                      $prop = 'current_mood';
 423                      $val = $this->moods[ $post['props']['current_moodid'] ];
 424                  } else {
 425                      $val = $post['props'][$prop];
 426                  }
 427                  add_post_meta( $post_id, 'lj_' . $prop, $val );
 428              }
 429          }
 430      }
 431  
 432      // Set up a session (authenticate) with LJ
 433  	function get_session() {
 434          // Get a session via XMLRPC
 435          $cookie = $this->lj_ixr( 'sessiongenerate', array( 'ver' => 1, 'expiration' => 'short' ) );
 436          if ( is_wp_error( $cookie ) )
 437              return new WP_Error( 'cookie', __( 'Could not get a cookie from LiveJournal. Please try again soon.' ) );
 438          return new WP_Http_Cookie( array( 'name' => 'ljsession', 'value' => $cookie['ljsession'] ) );
 439      }
 440  
 441      // Loops through and gets comment meta from LJ in batches
 442  	function download_comment_meta() {
 443          $cookie = $this->get_session();
 444          if ( is_wp_error( $cookie ) )
 445              return $cookie;
 446  
 447          // Load previous state (if any)
 448          $this->usermap = (array) get_option( 'ljapi_usermap' );
 449          $maxid         = get_option( 'ljapi_maxid' ) ? get_option( 'ljapi_maxid' ) : 1;
 450          $highest_id    = get_option( 'ljapi_highest_id' ) ? get_option( 'ljapi_highest_id' ) : 0;
 451  
 452          // We need to loop over the metadata request until we have it all
 453          while ( $maxid > $highest_id ) {
 454              // Now get the meta listing
 455              $results = wp_remote_get( $this->comments_url . '?get=comment_meta&startid=' . ( $highest_id + 1 ),
 456                                          array( 'cookies' => array( $cookie ), 'timeout' => 20 ) );
 457              if ( is_wp_error( $results ) )
 458                  return new WP_Error( 'comment_meta', __( 'Failed to retrieve comment meta information from LiveJournal. Please try again soon.' ) );
 459  
 460              $results = wp_remote_retrieve_body( $results );
 461  
 462              // Get the maxid so we know if we have them all yet
 463              preg_match( '|<maxid>(\d+)</maxid>|', $results, $matches );
 464              if ( 0 == $matches[1] ) {
 465                  // No comment meta = no comments for this journal
 466                  echo '<p>' . __( 'You have no comments to import!' ) . '</p>';
 467                  update_option( 'ljapi_highest_id', 1 );
 468                  update_option( 'ljapi_highest_comment_id', 1 );
 469                  return false; // Bail out of comment importing entirely
 470              }
 471              $maxid = !empty( $matches[1] ) ? $matches[1] : $maxid;
 472  
 473              // Parse comments and get highest id available
 474              preg_match_all( '|<comment id=\'(\d+)\'|is', $results, $matches );
 475              foreach ( $matches[1] as $id ) {
 476                  if ( $id > $highest_id )
 477                      $highest_id = $id;
 478              }
 479  
 480              // Parse out the list of user mappings, and add it to the known list
 481              preg_match_all( '|<usermap id=\'(\d+)\' user=\'([^\']+)\' />|', $results, $matches );
 482              foreach ( $matches[1] as $count => $userid )
 483                  $this->usermap[$userid] = $matches[2][$count]; // need this in memory for translating ids => names
 484  
 485              wp_cache_flush();
 486          }
 487          // endwhile - should have seen all comment meta at this point
 488  
 489          update_option( 'ljapi_usermap',    $this->usermap );
 490          update_option( 'ljapi_maxid',      $maxid );
 491          update_option( 'ljapi_highest_id', $highest_id );
 492  
 493          echo '<p>' . __( ' Comment metadata downloaded successfully, proceeding with comment bodies...' ) . '</p>';
 494  
 495          return true;
 496      }
 497  
 498      // Downloads actual comment bodies from LJ
 499      // Inserts them all directly to the DB, with additional info stored in "spare" fields
 500  	function download_comment_bodies() {
 501          global $wpdb;
 502          $cookie = $this->get_session();
 503          if ( is_wp_error( $cookie ) )
 504              return $cookie;
 505  
 506          // Load previous state (if any)
 507          $this->usermap = (array) get_option( 'ljapi_usermap' );
 508          $maxid         = get_option( 'ljapi_maxid' ) ? (int) get_option( 'ljapi_maxid' ) : 1;
 509          $highest_id    = (int) get_option( 'ljapi_highest_comment_id' );
 510          $loop = 0;
 511          while ( $maxid > $highest_id && $loop < 5 ) { // We do 5 loops per call to avoid memory limits
 512              $loop++;
 513  
 514              // Get a batch of comments, using the highest_id we've already got as a starting point
 515              $results = wp_remote_get( $this->comments_url . '?get=comment_body&startid=' . ( $highest_id + 1 ),
 516                                          array( 'cookies' => array( $cookie ), 'timeout' => 20 ) );
 517              if ( is_wp_error( $results ) )
 518                  return new WP_Error( 'comment_bodies', __( 'Failed to retrieve comment bodies from LiveJournal. Please try again soon.' ) );
 519  
 520              $results = wp_remote_retrieve_body( $results );
 521  
 522              // Parse out each comment and insert directly
 523              preg_match_all( '|<comment id=\'(\d+)\'.*</comment>|iUs', $results, $matches );
 524              for ( $c = 0; $c < count( $matches[0] ); $c++ ) {
 525                  // Keep track of highest id seen
 526                  if ( $matches[1][$c] > $highest_id ) {
 527                      $highest_id = $matches[1][$c];
 528                      update_option( 'ljapi_highest_comment_id', $highest_id );
 529                  }
 530  
 531                  $comment = $matches[0][$c];
 532  
 533                  // Filter out any captured, deleted comments (nothing useful to import)
 534                  $comment = preg_replace( '|<comment id=\'\d+\' jitemid=\'\d+\' posterid=\'\d+\' state=\'D\'[^/]*/>|is', '', $comment );
 535  
 536                  // Parse this comment into an array and insert
 537                  $comment = $this->parse_comment( $comment );
 538                  $comment = wp_filter_comment( $comment );
 539                  $id = wp_insert_comment( $comment );
 540  
 541                  // Clear cache
 542                  clean_comment_cache( $id );
 543              }
 544  
 545              // Clear cache to preseve memory
 546              wp_cache_flush();
 547          }
 548          // endwhile - all comments downloaded and ready for bulk processing
 549  
 550          // Counter just used to show progress to user
 551          update_option( 'ljapi_comment_batch', ( (int) get_option( 'ljapi_comment_batch' ) + 1 ) );
 552  
 553          return true;
 554      }
 555  
 556      // Takes a block of XML and parses out all the elements of the comment
 557  	function parse_comment( $comment ) {
 558          global $wpdb;
 559  
 560          // Get the top-level attributes
 561          preg_match( '|<comment([^>]+)>|i', $comment, $attribs );
 562          preg_match( '| id=\'(\d+)\'|i', $attribs[1], $matches );
 563          $lj_comment_ID = $matches[1];
 564          preg_match( '| jitemid=\'(\d+)\'|i', $attribs[1], $matches );
 565          $lj_comment_post_ID = $matches[1];
 566          preg_match( '| posterid=\'(\d+)\'|i', $attribs[1], $matches );
 567          $comment_author_ID = isset( $matches[1] ) ? $matches[1] : 0;
 568          preg_match( '| parentid=\'(\d+)\'|i', $attribs[1], $matches ); // optional
 569          $lj_comment_parent = isset( $matches[1] ) ? $matches[1] : 0;
 570          preg_match( '| state=\'([SDFA])\'|i', $attribs[1], $matches ); // optional
 571          $lj_comment_state = isset( $matches[1] ) ? $matches[1] : 'A';
 572  
 573          // Clean up "subject" - this will become the first line of the comment in WP
 574          preg_match( '|<subject>(.*)</subject>|is', $comment, $matches );
 575          if ( isset( $matches[1] ) ) {
 576              $comment_subject = $wpdb->escape( trim( $matches[1] ) );
 577              if ( 'Re:' == $comment_subject )
 578                  $comment_subject = '';
 579          }
 580  
 581          // Get the body and HTMLize it
 582          preg_match( '|<body>(.*)</body>|is', $comment, $matches );
 583          $comment_content = !empty( $comment_subject ) ? $comment_subject . "\n\n" . $matches[1] : $matches[1];
 584          $comment_content = @html_entity_decode( $comment_content, ENT_COMPAT, get_option('blog_charset') );
 585          $comment_content = str_replace( '&apos;', "'", $comment_content );
 586          $comment_content = wpautop( $comment_content );
 587          $comment_content = str_replace( '<br>', '<br />', $comment_content );
 588          $comment_content = str_replace( '<hr>', '<hr />', $comment_content );
 589          $comment_content = preg_replace_callback( '|<(/?[A-Z]+)|', array( &$this, '_normalize_tag' ), $comment_content );
 590          $comment_content = $wpdb->escape( trim( $comment_content ) );
 591  
 592          // Get and convert the date
 593          preg_match( '|<date>(.*)</date>|i', $comment, $matches );
 594          $comment_date = trim( str_replace( array( 'T', 'Z' ), ' ', $matches[1] ) );
 595  
 596          // Grab IP if available
 597          preg_match( '|<property name=\'poster_ip\'>(.*)</property>|i', $comment, $matches ); // optional
 598          $comment_author_IP = isset( $matches[1] ) ? $matches[1] : '';
 599  
 600          // Try to get something useful for the comment author, especially if it was "my" comment
 601          $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          if ( get_option( 'ljapi_username' ) == $author ) {
 603              $user    = wp_get_current_user();
 604              $user_id = $user->ID;
 605              $author  = $user->display_name;
 606              $url     = trailingslashit( get_option( 'home' ) );
 607          } else {
 608              $user_id = 0;
 609              $url     = ( __( 'Anonymous' ) == $author ) ? '' : 'http://' . $author . '.livejournal.com/';
 610          }
 611  
 612          // Send back the array of details
 613          return array( 'lj_comment_ID' => $lj_comment_ID,
 614                          'lj_comment_post_ID' => $lj_comment_post_ID,
 615                          'lj_comment_parent' => ( !empty( $lj_comment_parent ) ? $lj_comment_parent : 0 ),
 616                          'lj_comment_state' => $lj_comment_state,
 617                          'comment_post_ID' => $this->get_wp_post_ID( $lj_comment_post_ID ),
 618                          'comment_author' => $author,
 619                          'comment_author_url' => $url,
 620                          'comment_author_email' => '',
 621                          'comment_content' => $comment_content,
 622                          'comment_date' => $comment_date,
 623                          'comment_author_IP' => ( !empty( $comment_author_IP ) ? $comment_author_IP : '' ),
 624                          'comment_approved' => ( in_array( $lj_comment_state, array( 'A', 'F' ) ) ? 1 : 0 ),
 625                          'comment_karma' => $lj_comment_ID, // Need this and next value until rethreading is done
 626                          'comment_agent' => $lj_comment_parent,
 627                          'comment_type' => 'livejournal',  // Custom type, so we can find it later for processing
 628                          'user_ID' => $user_id
 629                      );
 630      }
 631  
 632  
 633      // Gets the post_ID that a LJ post has been saved as within WP
 634  	function get_wp_post_ID( $post ) {
 635          global $wpdb;
 636  
 637          if ( empty( $this->postmap[$post] ) )
 638               $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 ) );
 639  
 640          return $this->postmap[$post];
 641      }
 642  
 643      // Gets the comment_ID that a LJ comment has been saved as within WP
 644  	function get_wp_comment_ID( $comment ) {
 645          global $wpdb;
 646          if ( empty( $this->commentmap[$comment] ) )
 647               $this->commentmap[$comment] = $wpdb->get_var( $wpdb->prepare( "SELECT comment_ID FROM $wpdb->comments WHERE comment_karma = %d", $comment ) );
 648          return $this->commentmap[$comment];
 649      }
 650  
 651  	function lj_ixr() {
 652          if ( $challenge = $this->ixr->query( 'LJ.XMLRPC.getchallenge' ) ) {
 653              $challenge = $this->ixr->getResponse();
 654          }
 655          if ( isset( $challenge['challenge'] ) ) {
 656              $params = array( 'username' => $this->username,
 657                              'auth_method' => 'challenge',
 658                              'auth_challenge' => $challenge['challenge'],
 659                              'auth_response' => md5( $challenge['challenge'] . md5( $this->password ) ) );
 660          } else {
 661              return new WP_Error( 'IXR', __( 'LiveJournal is not responding to authentication requests. Please wait a while and then try again.' ) );
 662          }
 663  
 664          $args = func_get_args();
 665          $method = array_shift( $args );
 666          if ( isset( $args[0] ) )
 667              $params = array_merge( $params, $args[0] );
 668          if ( $this->ixr->query( 'LJ.XMLRPC.' . $method, $params ) ) {
 669              return $this->ixr->getResponse();
 670          } else {
 671              return new WP_Error( 'IXR', __( 'XML-RPC Request Failed -- ' ) . $this->ixr->getErrorCode() . ': ' . $this->ixr->getErrorMessage() );
 672          }
 673      }
 674  
 675  	function dispatch() {
 676          if ( empty( $_REQUEST['step'] ) )
 677              $step = 0;
 678          else
 679              $step = (int) $_REQUEST['step'];
 680  
 681          $this->header();
 682  
 683          switch ( $step ) {
 684              case -1 :
 685                  $this->cleanup();
 686                  // Intentional no break
 687              case 0 :
 688                  $this->greet();
 689                  break;
 690              case 1 :
 691              case 2 :
 692              case 3 :
 693                  check_admin_referer( 'lj-api-import' );
 694                  $result = $this->{ 'step' . $step }();
 695                  if ( is_wp_error( $result ) ) {
 696                      $this->throw_error( $result, $step );
 697                  }
 698                  break;
 699          }
 700  
 701          $this->footer();
 702      }
 703  
 704      // Technically the first half of step 1, this is separated to allow for AJAX
 705      // calls. Sets up some variables and options and confirms authentication.
 706  	function setup() {
 707          global $verified;
 708          // Get details from form or from DB
 709          if ( !empty( $_POST['lj_username'] ) && !empty( $_POST['lj_password'] ) ) {
 710              // Store details for later
 711              $this->username = $_POST['lj_username'];
 712              $this->password = $_POST['lj_password'];
 713              update_option( 'ljapi_username', $this->username );
 714              update_option( 'ljapi_password', $this->password );
 715          } else {
 716              $this->username = get_option( 'ljapi_username' );
 717              $this->password = get_option( 'ljapi_password' );
 718          }
 719  
 720          // This is the password to set on protected posts
 721          if ( !empty( $_POST['protected_password'] ) ) {
 722              $this->protected_password = $_POST['protected_password'];
 723              update_option( 'ljapi_protected_password', $this->protected_password );
 724          } else {
 725              $this->protected_password = get_option( 'ljapi_protected_password' );
 726          }
 727  
 728          // Log in to confirm the details are correct
 729          if ( empty( $this->username ) || empty( $this->password ) ) {
 730              ?>
 731              <p><?php _e( 'Please enter your LiveJournal username <em>and</em> password so we can download your posts and comments.' ) ?></p>
 732              <p><a href="<?php echo esc_url($_SERVER['PHP_SELF'] . '?import=livejournal&amp;step=-1&amp;_wpnonce=' . wp_create_nonce( 'lj-api-import' ) . '&amp;_wp_http_referer=' . esc_attr( str_replace( '&step=1', '', $_SERVER['REQUEST_URI'] ) ) ) ?>"><?php _e( 'Start again' ) ?></a></p>
 733              <?php
 734              return false;
 735          }
 736          $verified = $this->lj_ixr( 'login' );
 737          if ( is_wp_error( $verified ) ) {
 738              if ( 100 == $this->ixr->getErrorCode() || 101 == $this->ixr->getErrorCode() ) {
 739                  delete_option( 'ljapi_username' );
 740                  delete_option( 'ljapi_password' );
 741                  delete_option( 'ljapi_protected_password' );
 742                  ?>
 743                  <p><?php _e( 'Logging in to LiveJournal failed. Check your username and password and try again.' ) ?></p>
 744                  <p><a href="<?php echo esc_url($_SERVER['PHP_SELF'] . '?import=livejournal&amp;step=-1&amp;_wpnonce=' . wp_create_nonce( 'lj-api-import' ) . '&amp;_wp_http_referer=' . esc_attr( str_replace( '&step=1', '', $_SERVER['REQUEST_URI'] ) ) ) ?>"><?php _e( 'Start again' ) ?></a></p>
 745                  <?php
 746                  return false;
 747              } else {
 748                  return $verified;
 749              }
 750          } else {
 751              update_option( 'ljapi_verified', 'yes' );
 752          }
 753  
 754          // Set up some options to avoid them autoloading (these ones get big)
 755          add_option( 'ljapi_sync_item_times',  '', '', 'no' );
 756          add_option( 'ljapi_usermap',          '', '', 'no' );
 757          update_option( 'ljapi_comment_batch', 0 );
 758  
 759          return true;
 760      }
 761  
 762      // Check form inputs and start importing posts
 763  	function step1() {
 764          global $verified;
 765          set_time_limit( 0 );
 766          update_option( 'ljapi_step', 1 );
 767          if ( !$this->ixr ) $this->ixr = new IXR_Client( $this->ixr_url, false, 80, 30 );
 768          if ( empty( $_POST['login'] ) ) {
 769              // We're looping -- load some details from DB
 770              $this->username = get_option( 'ljapi_username' );
 771              $this->password = get_option( 'ljapi_password' );
 772              $this->protected_password = get_option( 'ljapi_protected_password' );
 773          } else {
 774              // First run (non-AJAX)
 775              $setup = $this->setup();
 776              if ( !$setup ) {
 777                  return false;
 778              } else if ( is_wp_error( $setup ) ) {
 779                  $this->throw_error( $setup, 1 );
 780                  return false;
 781              }
 782          }
 783  
 784          echo '<div id="ljapi-status">';
 785          echo '<h3>' . __( 'Importing Posts' ) . '</h3>';
 786          echo '<p>' . __( 'We&#8217;re downloading and importing your LiveJournal posts...' ) . '</p>';
 787          if ( get_option( 'ljapi_post_batch' ) && count( get_option( 'ljapi_sync_item_times' ) ) ) {
 788              $batch = count( get_option( 'ljapi_sync_item_times' ) );
 789              $batch = $count > 300 ? ceil( $batch / 300 ) : 1;
 790              echo '<p><strong>' . sprintf( __( 'Imported post batch %d of <strong>approximately</strong> %d' ), ( get_option( 'ljapi_post_batch' ) + 1 ), $batch ) . '</strong></p>';
 791          }
 792          ob_flush(); flush();
 793  
 794          if ( !get_option( 'ljapi_lastsync' ) || '1900-01-01 00:00:00' == get_option( 'ljapi_lastsync' ) ) {
 795              // We haven't downloaded meta yet, so do that first
 796              $result = $this->download_post_meta();
 797              if ( is_wp_error( $result ) ) {
 798                  $this->throw_error( $result, 1 );
 799                  return false;
 800              }
 801          }
 802  
 803          // Download a batch of actual posts
 804          $result = $this->download_post_bodies();
 805          if ( is_wp_error( $result ) ) {
 806              if ( 406 == $this->ixr->getErrorCode() ) {
 807                  ?>
 808                  <p><strong><?php _e( 'Uh oh &ndash; LiveJournal has disconnected us because we made too many requests to their servers too quickly.' ) ?></strong></p>
 809                  <p><strong><?php _e( 'We&#8217;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>
 810                  <?php
 811                  echo $this->next_step( 1, __( 'Try Again' ) );
 812                  return false;
 813              } else {
 814                  $this->throw_error( $result, 1 );
 815                  return false;
 816              }
 817          }
 818  
 819          if ( get_option( 'ljapi_last_sync_count' ) > 0 ) {
 820          ?>
 821              <form action="admin.php?import=livejournal" method="post" id="ljapi-auto-repost">
 822              <?php wp_nonce_field( 'lj-api-import' ) ?>
 823              <input type="hidden" name="step" id="step" value="1" />
 824              <p><input type="submit" class="button-primary" value="<?php esc_attr_e( 'Import the next batch' ) ?>" /> <span id="auto-message"></span></p>
 825              </form>
 826              <?php $this->auto_ajax( 'ljapi-auto-repost', 'auto-message', 0 ); ?>
 827          <?php
 828          } else {
 829              echo '<p>' . __( 'Your posts have all been imported, but wait &#8211; there&#8217;s more! Now we need to download &amp; import your comments.' ) . '</p>';
 830              echo $this->next_step( 2, __( 'Download my comments &raquo;' ) );
 831              $this->auto_submit();
 832          }
 833          echo '</div>';
 834      }
 835  
 836      // Download comments to local XML
 837  	function step2() {
 838          set_time_limit( 0 );
 839          update_option( 'ljapi_step', 2 );
 840          $this->username = get_option( 'ljapi_username' );
 841          $this->password = get_option( 'ljapi_password' );
 842          $this->ixr = new IXR_Client( $this->ixr_url, false, 80, 30 );
 843  
 844          echo '<div id="ljapi-status">';
 845          echo '<h3>' . __( 'Downloading Comments' ) . '</h3>';
 846          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>';
 847          ob_flush(); flush();
 848  
 849          if ( !get_option( 'ljapi_usermap' ) ) {
 850              // We haven't downloaded meta yet, so do that first
 851              $result = $this->download_comment_meta();
 852              if ( is_wp_error( $result ) ) {
 853                  $this->throw_error( $result, 2 );
 854                  return false;
 855              }
 856          }
 857  
 858          // Download a batch of actual comments
 859          $result = $this->download_comment_bodies();
 860          if ( is_wp_error( $result ) ) {
 861              $this->throw_error( $result, 2 );
 862              return false;
 863          }
 864  
 865          $maxid      = get_option( 'ljapi_maxid' ) ? (int) get_option( 'ljapi_maxid' ) : 1;
 866          $highest_id = (int) get_option( 'ljapi_highest_comment_id' );
 867          if ( $maxid > $highest_id ) {
 868              $batch = $maxid > 5000 ? ceil( $maxid / 5000 ) : 1;
 869          ?>
 870              <form action="admin.php?import=livejournal" method="post" id="ljapi-auto-repost">
 871              <p><strong><?php printf( __( 'Imported comment batch %d of <strong>approximately</strong> %d' ), get_option( 'ljapi_comment_batch' ), $batch ) ?></strong></p>
 872              <?php wp_nonce_field( 'lj-api-import' ) ?>
 873              <input type="hidden" name="step" id="step" value="2" />
 874              <p><input type="submit" class="button-primary" value="<?php esc_attr_e( 'Import the next batch' ) ?>" /> <span id="auto-message"></span></p>
 875              </form>
 876              <?php $this->auto_ajax( 'ljapi-auto-repost', 'auto-message', 0 ); ?>
 877          <?php
 878          } else {
 879              echo '<p>' . __( 'Your comments have all been imported now, but we still need to rebuild your conversation threads.' ) . '</p>';
 880              echo $this->next_step( 3, __( 'Rebuild my comment threads &raquo;' ) );
 881              $this->auto_submit();
 882          }
 883          echo '</div>';
 884      }
 885  
 886      // Re-thread comments already in the DB
 887  	function step3() {
 888          global $wpdb;
 889          set_time_limit( 0 );
 890          update_option( 'ljapi_step', 3 );
 891  
 892          echo '<div id="ljapi-status">';
 893          echo '<h3>' . __( 'Threading Comments' ) . '</h3>';
 894          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>';
 895          ob_flush(); flush();
 896  
 897          // Only bother adding indexes if they have over 5000 comments (arbitrary number)
 898          $imported_comments = $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->comments} WHERE comment_type = 'livejournal'" );
 899          $added_indices = false;
 900          if ( 5000 < $imported_comments ) {
 901              include_once (ABSPATH . 'wp-admin/includes/upgrade.php');
 902              $added_indices = true;
 903              add_clean_index( $wpdb->comments, 'comment_type'  );
 904              add_clean_index( $wpdb->comments, 'comment_karma' );
 905              add_clean_index( $wpdb->comments, 'comment_agent' );
 906          }
 907  
 908          // Get LJ comments, which haven't been threaded yet, 5000 at a time and thread them
 909          while ( $comments = $wpdb->get_results( "SELECT comment_ID, comment_agent FROM {$wpdb->comments} WHERE comment_type = 'livejournal' AND comment_agent != '0' LIMIT 5000", OBJECT ) ) {
 910              foreach ( $comments as $comment ) {
 911                  $wpdb->update( $wpdb->comments,
 912                                  array( 'comment_parent' => $this->get_wp_comment_ID( $comment->comment_agent ), 'comment_type' => 'livejournal-done' ),
 913                                  array( 'comment_ID' => $comment->comment_ID ) );
 914              }
 915              wp_cache_flush();
 916              $wpdb->flush();
 917          }
 918  
 919          // Revert the comments table back to normal and optimize it to reclaim space
 920          if ( $added_indices ) {
 921              drop_index( $wpdb->comments, 'comment_type'  );
 922              drop_index( $wpdb->comments, 'comment_karma' );
 923              drop_index( $wpdb->comments, 'comment_agent' );
 924              $wpdb->query( "OPTIMIZE TABLE {$wpdb->comments}" );
 925          }
 926  
 927          // Clean up database and we're out
 928          $this->cleanup();
 929          do_action( 'import_done', 'livejournal' );
 930          if ( $imported_comments > 1 )
 931              echo '<p>' . sprintf( __( "Successfully re-threaded %s comments." ), number_format( $imported_comments ) ) . '</p>';
 932          echo '<h3>';
 933          printf( __( 'All done. <a href="%s">Have fun!</a>' ), get_option( 'home' ) );
 934          echo '</h3>';
 935          echo '</div>';
 936      }
 937  
 938      // Output an error message with a button to try again.
 939  	function throw_error( $error, $step ) {
 940          echo '<p><strong>' . $error->get_error_message() . '</strong></p>';
 941          echo $this->next_step( $step, __( 'Try Again' ) );
 942      }
 943  
 944      // Returns the HTML for a link to the next page
 945  	function next_step( $next_step, $label, $id = 'ljapi-next-form' ) {
 946          $str  = '<form action="admin.php?import=livejournal" method="post" id="' . $id . '">';
 947          $str .= wp_nonce_field( 'lj-api-import', '_wpnonce', true, false );
 948          $str .= wp_referer_field( false );
 949          $str .= '<input type="hidden" name="step" id="step" value="' . esc_attr($next_step) . '" />';
 950          $str .= '<p><input type="submit" class="button-primary" value="' . esc_attr( $label ) . '" /> <span id="auto-message"></span></p>';
 951          $str .= '</form>';
 952  
 953          return $str;
 954      }
 955  
 956      // Automatically submit the specified form after $seconds
 957      // Include a friendly countdown in the element with id=$msg
 958  	function auto_submit( $id = 'ljapi-next-form', $msg = 'auto-message', $seconds = 10 ) {
 959          ?><script type="text/javascript">
 960              next_counter = <?php echo $seconds ?>;
 961              jQuery(document).ready(function(){
 962                  ljapi_msg();
 963              });
 964  
 965  			function ljapi_msg() {
 966                  str = '<?php _e( "Continuing in %d" ) ?>';
 967                  jQuery( '#<?php echo $msg ?>' ).text( str.replace( /%d/, next_counter ) );
 968                  if ( next_counter <= 0 ) {
 969                      if ( jQuery( '#<?php echo $id ?>' ).length ) {
 970                          jQuery( "#<?php echo $id ?> input[type='submit']" ).hide();
 971                          str = '<?php _e( "Continuing" ) ?> <img src="images/wpspin_light.gif" alt="" id="processing" align="top" />';
 972                          jQuery( '#<?php echo $msg ?>' ).html( str );
 973                          jQuery( '#<?php echo $id ?>' ).submit();
 974                          return;
 975                      }
 976                  }
 977                  next_counter = next_counter - 1;
 978                  setTimeout('ljapi_msg()', 1000);
 979              }
 980          </script><?php
 981      }
 982  
 983      // Automatically submit the form with #id to continue the process
 984      // Hide any submit buttons to avoid people clicking them
 985      // Display a countdown in the element indicated by $msg for "Continuing in x"
 986  	function auto_ajax( $id = 'ljapi-next-form', $msg = 'auto-message', $seconds = 5 ) {
 987          ?><script type="text/javascript">
 988              next_counter = <?php echo $seconds ?>;
 989              jQuery(document).ready(function(){
 990                  ljapi_msg();
 991              });
 992  
 993  			function ljapi_msg() {
 994                  str = '<?php _e( "Continuing in %d" ) ?>';
 995                  jQuery( '#<?php echo $msg ?>' ).text( str.replace( /%d/, next_counter ) );
 996                  if ( next_counter <= 0 ) {
 997                      if ( jQuery( '#<?php echo $id ?>' ).length ) {
 998                          jQuery( "#<?php echo $id ?> input[type='submit']" ).hide();
 999                          jQuery.ajaxSetup({'timeout':3600000});
1000                          str = '<?php _e( "Processing next batch." ) ?> <img src="images/wpspin_light.gif" alt="" id="processing" align="top" />';
1001                          jQuery( '#<?php echo $msg ?>' ).html( str );
1002                          jQuery('#ljapi-status').load(ajaxurl, {'action':'lj-importer',
1003                                                                  'step':jQuery('#step').val(),
1004                                                                  '_wpnonce':'<?php echo wp_create_nonce( 'lj-api-import' ) ?>',
1005                                                                  '_wp_http_referer':'<?php echo $_SERVER['REQUEST_URI'] ?>'});
1006                          return;
1007                      }
1008                  }
1009                  next_counter = next_counter - 1;
1010                  setTimeout('ljapi_msg()', 1000);
1011              }
1012          </script><?php
1013      }
1014  
1015      // Remove all options used during import process and
1016      // set wp_comments entries back to "normal" values
1017  	function cleanup() {
1018          global $wpdb;
1019  
1020          delete_option( 'ljapi_username' );
1021          delete_option( 'ljapi_password' );
1022          delete_option( 'ljapi_protected_password' );
1023          delete_option( 'ljapi_verified' );
1024          delete_option( 'ljapi_total' );
1025          delete_option( 'ljapi_count' );
1026          delete_option( 'ljapi_lastsync' );
1027          delete_option( 'ljapi_last_sync_count' );
1028          delete_option( 'ljapi_sync_item_times' );
1029          delete_option( 'ljapi_lastsync_posts' );
1030          delete_option( 'ljapi_post_batch' );
1031          delete_option( 'ljapi_imported_count' );
1032          delete_option( 'ljapi_maxid' );
1033          delete_option( 'ljapi_usermap' );
1034          delete_option( 'ljapi_highest_id' );
1035          delete_option( 'ljapi_highest_comment_id' );
1036          delete_option( 'ljapi_comment_batch' );
1037          delete_option( 'ljapi_step' );
1038  
1039          $wpdb->update( $wpdb->comments,
1040                          array( 'comment_karma' => 0, 'comment_agent' => 'WP LJ Importer', 'comment_type' => '' ),
1041                          array( 'comment_type' => 'livejournal-done' ) );
1042          $wpdb->update( $wpdb->comments,
1043                          array( 'comment_karma' => 0, 'comment_agent' => 'WP LJ Importer', 'comment_type' => '' ),
1044                          array( 'comment_type' => 'livejournal' ) );
1045      }
1046  
1047  	function LJ_API_Import() {
1048          $this->__construct();
1049      }
1050  
1051  	function __construct() {
1052          // Nothing
1053      }
1054  }
1055  
1056  $lj_api_import = new LJ_API_Import();
1057  
1058  register_importer( 'livejournal', __( 'LiveJournal' ), __( 'Import posts from LiveJournal using their API.' ), array( $lj_api_import, 'dispatch' ) );
1059  ?>


Generated: Fri Jan 8 00:19:48 2010 Cross-referenced by PHPXref 0.7