<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[2178] 2013/frederickding/importer/trunk: A huge set of changes related to #340.</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://gsoc.trac.wordpress.org/changeset/2178">2178</a></dd>
<dt>Author</dt> <dd>frederick.ding</dd>
<dt>Date</dt> <dd>2013-07-30 01:15:34 +0000 (Tue, 30 Jul 2013)</dd>
</dl>

<h3>Log Message</h3>
<pre>A huge set of changes related to <a href="http://gsoc.trac.wordpress.org/ticket/340">#340</a>.

- UI works -- mostly. Status page is still very rough (currently using `var_dump()`).
- Fixed issue with cron schedule not being loaded -- should now be hooked in.
- *DO NOT USE*; might still not be fully functional!</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#2013frederickdingimportertrunkclasswordpressimporterphp">2013/frederickding/importer/trunk/class-wordpress-importer.php</a></li>
<li><a href="#2013frederickdingimportertrunkclasswpimportercronphp">2013/frederickding/importer/trunk/class-wp-importer-cron.php</a></li>
<li><a href="#2013frederickdingimportertrunkwordpressimporterphp">2013/frederickding/importer/trunk/wordpress-importer.php</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="2013frederickdingimportertrunkclasswordpressimporterphp"></a>
<div class="modfile"><h4>Modified: 2013/frederickding/importer/trunk/class-wordpress-importer.php (2177 => 2178)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/frederickding/importer/trunk/class-wordpress-importer.php   2013-07-30 01:14:00 UTC (rev 2177)
+++ 2013/frederickding/importer/trunk/class-wordpress-importer.php      2013-07-30 01:15:34 UTC (rev 2178)
</span><span class="lines">@@ -20,13 +20,6 @@
</span><span class="cx">  const MAX_WXR_VERSION = 1.2;
</span><span class="cx"> 
</span><span class="cx">  /**
</span><del>-        * Attachment ID of the WXR file.
-        *
-        * @var int
-        */
-       protected $id;
-
-       /**
</del><span class="cx">    * WXR version of the file to be imported.
</span><span class="cx">   *
</span><span class="cx">   * @var float
</span><span class="lines">@@ -67,7 +60,7 @@
</span><span class="cx">   *
</span><span class="cx">   * @var array
</span><span class="cx">   */
</span><del>-       protected $_wxr_data = array();
</del><ins>+        protected $wxr_data = array();
</ins><span class="cx"> 
</span><span class="cx">  /*
</span><span class="cx">   * SECTION: parsed data from import file
</span><span class="lines">@@ -202,10 +195,13 @@
</span><span class="cx">   *
</span><span class="cx">   * @param string $file
</span><span class="cx">   *              Path to the WXR file for parsing
</span><ins>+        * @param boolean $independent
+        *                      Set to true if the parsing is a trial run or needs to be
+        *          independent of the cron import process; false by default.
</ins><span class="cx">    * @return array WP_Error data if successful, or an instance of WP_Error if
</span><span class="cx">   *         a problem occurred
</span><span class="cx">   */
</span><del>-       public function do_parse( $file ) {
</del><ins>+        public function do_parse( $file, $independent = false ) {
</ins><span class="cx">           if ( ! is_file( $file ) ) {
</span><span class="cx">                  return new WP_Error( 'import_wxr_error',
</span><span class="cx">                                  __( 'The file does not exist, please try again.',
</span><span class="lines">@@ -220,31 +216,34 @@
</span><span class="cx">          if ( is_wp_error( $data ) )
</span><span class="cx">                  return $data;
</span><span class="cx"> 
</span><del>-                       // check for acceptable version
</del><ins>+                // check for acceptable version
</ins><span class="cx">           $version = floatval( $data['version'] );
</span><span class="cx">          if ( $version > self::MAX_WXR_VERSION ) {
</span><del>-                       return new WP_Error( 'import_wxr_error',
</del><ins>+                        return new WP_Error( 'import_wxr_version_error',
</ins><span class="cx">                                   __( 'WXR version newer than importer',
</span><del>-                                                       'wordpress-importer' ), $version );
</del><ins>+                                                        'wordpress-importer' ), $data['version'] );
</ins><span class="cx">           }
</span><span class="cx"> 
</span><del>-               $this->version = $version;
</del><span class="cx">           $this->wxr_file = $file;
</span><del>-               $this->categories = $data['categories'];
-               $this->tags = $data['tags'];
-               $this->terms = $data['terms'];
-               $this->posts = $data['posts'];
</del><ins>+                $this->wxr_data = $data;
</ins><span class="cx"> 
</span><del>-               $this->set_param('base_url', esc_url( $data['base_url'] ));
</del><ins>+                if ( ! $independent ) {
+                       $this->version = $version;
+                       $this->categories = $data['categories'];
+                       $this->tags = $data['tags'];
+                       $this->terms = $data['terms'];
+                       $this->posts = $data['posts'];
</ins><span class="cx"> 
</span><del>-               $this->_wxr_data = $data;
-               if ( $user = get_current_user_id() > 0 ) {
-                       $this->set_param( 'admin_user_id', $user );
</del><ins>+                        if ( ($user = get_current_user_id()) > 0 ) {
+                               $this->set_param( 'admin_user_id', $user );
+                       }
+
+                       $this->set_param( 'base_url', esc_url( $data['base_url'] ) );
+
+                       wp_defer_term_counting( true );
+                       wp_defer_comment_counting( true );
</ins><span class="cx">           }
</span><span class="cx"> 
</span><del>-               wp_defer_term_counting( true );
-               wp_defer_comment_counting( true );
-
</del><span class="cx">           /**
</span><span class="cx">           *
</span><span class="cx">           * @todo persistent storage without taking up too much space, or more
</span><span class="lines">@@ -254,9 +253,13 @@
</span><span class="cx">  }
</span><span class="cx"> 
</span><span class="cx">  /**
</span><del>-        * The main controller for the actual import stage. Modelled on
-        * Tumblr_Import::do_blog_import().
</del><ins>+         * The main controller for the actual import stage. Should be called from a
+        * scheduled cron job using
+        * <code>$this->schedule_import_job( 'do_import', array($file) );</code>
+        * but it can be executed directly.
</ins><span class="cx">    *
</span><ins>+        * Modelled on Tumblr_Import::do_blog_import().
+        *
</ins><span class="cx">    * @param string $file
</span><span class="cx">   *              Path to the WXR file for importing
</span><span class="cx">   * @return boolean Whether the import process is complete
</span><span class="lines">@@ -402,19 +405,23 @@
</span><span class="cx">   * Like all process_* methods, this will return true when its step has
</span><span class="cx">   * completed.
</span><span class="cx">   *
</span><del>-        * @return boolean True upon completion, false otherwise, if an error has occurred
</del><ins>+         * @param boolean $autoadvance
+        *              If true (default), advance to the next step
+        *              automatically after completion; otherwise, do not advance
+        * @return boolean True upon completion, false otherwise, if an error has
+        *         occurred
</ins><span class="cx">    */
</span><del>-       protected function process_authors() {
</del><ins>+        protected function process_authors( $autoadvance = true ) {
</ins><span class="cx">           // check for availability of data
</span><del>-               if ( empty( $this->wxr_file ) || empty( $this->_wxr_data ) ) {
</del><ins>+                if ( empty( $this->wxr_file ) || empty( $this->wxr_data ) ) {
</ins><span class="cx">                   $this->error = new WP_Error( 'import_process_wxr_error',
</span><span class="cx">                                  __( 'No parsed data available for processing',
</span><span class="cx">                                                  'wordpress-importer' ) );
</span><span class="cx">                  return false;
</span><span class="cx">          }
</span><span class="cx"> 
</span><del>-               if ( ! empty( $this->_wxr_data['authors'] ) ) {
-                       $this->authors = $this->_wxr_data['authors'];
</del><ins>+                if ( ! empty( $this->wxr_data['authors'] ) ) {
+                       $this->authors = $this->wxr_data['authors'];
</ins><span class="cx">           } else {
</span><span class="cx">                  // no author information, grab it from the posts
</span><span class="cx">                  foreach ( $this->_['posts'] as $post ) {
</span><span class="lines">@@ -438,8 +445,11 @@
</span><span class="cx">                  }
</span><span class="cx">          }
</span><span class="cx"> 
</span><del>-               // done without fatal errors, so we'll advance step
-               $this->advance();
</del><ins>+                if ( $autoadvance ) {
+                       unset($this->wxr_data);
+                       // done without fatal errors, so we'll advance step
+                       $this->advance();
+               }
</ins><span class="cx">           return true;
</span><span class="cx">  }
</span><span class="cx"> 
</span><span class="lines">@@ -602,8 +612,8 @@
</span><span class="cx">                          if ( isset( $cat['term_id'] ) )
</span><span class="cx">                                  $this->processed_terms[intval( $cat['term_id'] )] = $id;
</span><span class="cx">                  } else {
</span><del>-                                       // set a warning in the importer class, and include the
-                                       // WP_Error object emitted by wp_insert_category() as data.
</del><ins>+                                // set a warning in the importer class, and include the
+                               // WP_Error object emitted by wp_insert_category() as data.
</ins><span class="cx">                           $this->warnings[] = new WP_Error(
</span><span class="cx">                                          'import_process_categories_warning',
</span><span class="cx">                                          sprintf(
</span><span class="lines">@@ -744,12 +754,15 @@
</span><span class="cx">   *
</span><span class="cx">   * @param array $post
</span><span class="cx">   * @param string $url
</span><del>-        * @return int|WP_Error
</del><ins>+         * @return int
</ins><span class="cx">    */
</span><span class="cx">  protected function process_attachment( $post, $url ) {
</span><del>-               if ( ! $this->is_allowed_attachment_fetch() )
-                   return new WP_Error( 'attachment_processing_error',
</del><ins>+                if ( ! $this->get_param( 'fetch_attachments', true ) ||
+                                ! $this->is_allowed_attachment_fetch() ) {
+                   $this->warnings[] = new WP_Error( 'attachment_processing_error',
</ins><span class="cx">                   __( 'Fetching attachments is not enabled', 'wordpress-importer' ) );
</span><ins>+                   return 0;
+               }
</ins><span class="cx"> 
</span><span class="cx">          // if the URL is absolute, but does not contain address, then upload it assuming base_site_url
</span><span class="cx">          if ( preg_match( '|^/[\w\W]+$|', $url ) )
</span><span class="lines">@@ -1519,6 +1532,39 @@
</span><span class="cx">  }
</span><span class="cx"> 
</span><span class="cx">  /**
</span><ins>+        * Returns the version of the loaded WXR file.
+        *
+        * @return float
+        */
+       public function get_version() {
+               return $this->version;
+       }
+
+       /**
+        * Retrieves the authors from the WXR file.
+        *
+        * Necessary for UI interface.
+        *
+        * @return array
+        */
+       public function get_authors() {
+               // runs process_authors() once if it has never been done
+               if ( empty( $this->authors ) ) {
+                       // explicitly tell process_authors() NOT to advance
+                       $this->process_authors(false);
+
+                       // pass through error if there was one, then clear it
+                       if ( is_wp_error( $this->error ) ) {
+                               $error = $this->error;
+                               unset($this->error);
+                               return $error;
+                       }
+               }
+
+               return $this->authors;
+       }
+
+       /**
</ins><span class="cx">    * Stores parameters typically used for user input.
</span><span class="cx">   *
</span><span class="cx">   * Previously, some of these params would have been directly accessed with
</span></span></pre></div>
<a id="2013frederickdingimportertrunkclasswpimportercronphp"></a>
<div class="modfile"><h4>Modified: 2013/frederickding/importer/trunk/class-wp-importer-cron.php (2177 => 2178)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/frederickding/importer/trunk/class-wp-importer-cron.php     2013-07-30 01:14:00 UTC (rev 2177)
+++ 2013/frederickding/importer/trunk/class-wp-importer-cron.php        2013-07-30 01:15:34 UTC (rev 2178)
</span><span class="lines">@@ -13,7 +13,7 @@
</span><span class="cx"> 
</span><span class="cx">  require_once ABSPATH . 'wp-admin/includes/import.php';
</span><span class="cx"> 
</span><del>-       if ( !class_exists( 'WP_Importer' ) ) {
</del><ins>+        if ( ! class_exists( 'WP_Importer' ) ) {
</ins><span class="cx">           $class_wp_importer = ABSPATH . 'wp-admin/includes/class-wp-importer.php';
</span><span class="cx">          if ( file_exists( $class_wp_importer ) ) {
</span><span class="cx">                  require_once $class_wp_importer;
</span><span class="lines">@@ -33,6 +33,13 @@
</span><span class="cx">  class WP_Importer_Cron extends WP_Importer {
</span><span class="cx"> 
</span><span class="cx">          /**
</span><ins>+                * Timestamp of when this object was constructed.
+                *
+                * @var int
+                */
+               protected $_importer_started;
+
+               /**
</ins><span class="cx">            * Instantiates a new cron-based importer object.
</span><span class="cx">           *
</span><span class="cx">           * If this method is overrided by a child class, it is crucial that the
</span><span class="lines">@@ -52,8 +59,10 @@
</span><span class="cx">                  add_action( 'wp_cron_importer_hook', array( $this, 'importer_callback' ) );
</span><span class="cx"> 
</span><span class="cx">                  // crucial! for preventing cache breaking
</span><del>-                       wp_suspend_cache_invalidation( true );
-                       wp_suspend_cache_addition( true );
</del><ins>+                        if ( defined( 'WP_LOAD_IMPORTERS' ) || defined( 'DOING_CRON' ) ) {
+                               wp_suspend_cache_invalidation( true );
+                               wp_suspend_cache_addition( true );
+                       }
</ins><span class="cx"> 
</span><span class="cx">                  // load the variables
</span><span class="cx">                  $options = get_option( get_class($this) );
</span><span class="lines">@@ -140,7 +149,7 @@
</span><span class="cx">          function save_vars() {
</span><span class="cx">                  $vars = get_object_vars( $this );
</span><span class="cx">                  foreach ( $vars as $var => $val ) {
</span><del>-                               if ( $var[0] == "_" )
</del><ins>+                                if ( $var[0] == '_' )
</ins><span class="cx">                                   unset( $vars[$var] );
</span><span class="cx">                  }
</span><span class="cx">                  update_option( get_class( $this ), $vars );
</span></span></pre></div>
<a id="2013frederickdingimportertrunkwordpressimporterphp"></a>
<div class="modfile"><h4>Modified: 2013/frederickding/importer/trunk/wordpress-importer.php (2177 => 2178)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/frederickding/importer/trunk/wordpress-importer.php 2013-07-30 01:14:00 UTC (rev 2177)
+++ 2013/frederickding/importer/trunk/wordpress-importer.php    2013-07-30 01:15:34 UTC (rev 2178)
</span><span class="lines">@@ -13,7 +13,7 @@
</span><span class="cx"> at revision 718670.
</span><span class="cx"> */
</span><span class="cx"> 
</span><del>-if ( ! defined( 'WP_LOAD_IMPORTERS' ) )
</del><ins>+if ( ! defined( 'WP_LOAD_IMPORTERS' ) && ! defined( 'DOING_CRON' ) )
</ins><span class="cx">   return;
</span><span class="cx"> 
</span><span class="cx"> /** Display verbose errors */
</span><span class="lines">@@ -25,7 +25,7 @@
</span><span class="cx"> require dirname(__FILE__) . '/class-wp-importer-cron.php';
</span><span class="cx"> require dirname( __FILE__ ) . '/class-wxr-parser.php';
</span><span class="cx"> 
</span><del>-// Load specifc cron importer implementation
</del><ins>+// Load specific cron importer implementation
</ins><span class="cx"> if ( ! class_exists( 'WordPress_Importer' ) ) {
</span><span class="cx">     require dirname(__FILE__) . '/class-wordpress-importer.php';
</span><span class="cx"> }
</span><span class="lines">@@ -36,7 +36,6 @@
</span><span class="cx">  * @package WordPress
</span><span class="cx">  * @subpackage Importer
</span><span class="cx">  */
</span><del>-if ( class_exists( 'WP_Importer' ) ) {
</del><span class="cx"> class WP_Import extends WP_Importer {
</span><span class="cx"> 
</span><span class="cx">  var $id; // WXR attachment ID
</span><span class="lines">@@ -48,7 +47,9 @@
</span><span class="cx">   */
</span><span class="cx">  protected $importer;
</span><span class="cx"> 
</span><del>-       function WP_Import() { /* nothing */ }
</del><ins>+        function __construct() {
+           $this->importer = new WordPress_Importer();
+       }
</ins><span class="cx"> 
</span><span class="cx">  /**
</span><span class="cx">   * Registered callback function for the WordPress Importer
</span><span class="lines">@@ -70,14 +71,16 @@
</span><span class="cx">                          break;
</span><span class="cx">                  case 2:
</span><span class="cx">                          check_admin_referer( 'import-wordpress' );
</span><del>-                                       $this->fetch_attachments = (! empty(
-                                                       $_POST['fetch_attachments'] ) &&
-                                                        $this->importer->is_allowed_attachment_fetch());
</del><ins>+
</ins><span class="cx">                           $this->id = (int) $_POST['import_id'];
</span><span class="cx">                          $file = get_attached_file( $this->id );
</span><span class="cx">                          set_time_limit(0);
</span><span class="cx">                          $this->import( $file );
</span><span class="cx">                          break;
</span><ins>+                       case 3:
+                               // status
+                               $this->status();
+                               break;
</ins><span class="cx">           }
</span><span class="cx"> 
</span><span class="cx">          $this->footer();
</span><span class="lines">@@ -94,21 +97,13 @@
</span><span class="cx"> 
</span><span class="cx">          $this->import_start( $file );
</span><span class="cx"> 
</span><del>-               $this->get_author_mapping();
-
-               wp_suspend_cache_invalidation( true );
-               $this->process_categories();
-               $this->process_tags();
-               $this->process_terms();
-               $this->process_posts();
-               wp_suspend_cache_invalidation( false );
-
-               // update incorrect/missing information in the DB
-               $this->backfill_parents();
-               $this->backfill_attachment_urls();
-               $this->remap_featured_images();
-
-               $this->import_end();
</del><ins>+                if ( wp_next_scheduled( 'wp_cron_importer_hook', array(
+                               $file
+               ) ) !== false ) {
+                       // cron job is not finished; can't end import yet
+                       $this->status();
+               } else
+                       $this->import_end();
</ins><span class="cx">   }
</span><span class="cx"> 
</span><span class="cx">  /**
</span><span class="lines">@@ -133,6 +128,21 @@
</span><span class="cx">                  die();
</span><span class="cx">          }
</span><span class="cx"> 
</span><ins>+               $this->importer->set_param( 'fetch_attachments',
+                   (! empty( $_POST['fetch_attachments'] ) &&
+                       $this->importer->is_allowed_attachment_fetch()) );
+               $this->importer->set_param( 'user_new',
+                   (! empty( $_POST['user_new'] ) ? $_POST['user_new'] : array()) );
+               $this->importer->set_param( 'user_map',
+                   (! empty( $_POST['user_map'] ) ? $_POST['user_map'] : array()) );
+               $this->importer->set_param( 'imported_authors',
+                   (! empty( $_POST['imported_authors'] ) ? $_POST['imported_authors'] : array()) );
+
+               $this->importer->advance('start');
+
+               $this->importer->schedule_import_job( 'do_import', array( $file ) );
+               $this->importer->save_vars();
+
</ins><span class="cx">           do_action( 'import_start' );
</span><span class="cx">  }
</span><span class="cx"> 
</span><span class="lines">@@ -157,74 +167,61 @@
</span><span class="cx">   */
</span><span class="cx">  function handle_upload() {
</span><span class="cx">          $file = wp_import_handle_upload();
</span><del>-
</del><span class="cx">           if ( isset( $file['error'] ) ) {
</span><del>-                       echo '<p><strong>' . __( 'Sorry, there has been an error.', 'wordpress-importer' ) . '</strong><br />';
</del><ins>+                        echo '<p><strong>' . __( 'Sorry, there has been an error.',
+                                       'wordpress-importer' ) . '</strong><br />';
</ins><span class="cx">                   echo esc_html( $file['error'] ) . '</p>';
</span><span class="cx">                  return false;
</span><del>-               } else if ( ! file_exists( $file['file'] ) ) {
-                       echo '<p><strong>' . __( 'Sorry, there has been an error.', 'wordpress-importer' ) . '</strong><br />';
-                       printf( __( 'The export file could not be found at <code>%s</code>. It is likely that this was caused by a permissions problem.', 'wordpress-importer' ), esc_html( $file['file'] ) );
-                       echo '</p>';
-                       return false;
-               }
</del><ins>+                } else
+                       if ( ! file_exists( $file['file'] ) ) {
+                               echo '<p><strong>' . __( 'Sorry, there has been an error.',
+                                               'wordpress-importer' ) . '</strong><br />';
+                               printf(
+                                               __(
+                                                               'The export file could not be found at <code>%s</code>. It is likely that this was caused by a permissions problem.',
+                                                               'wordpress-importer' ),
+                                               esc_html( $file['file'] ) );
+                               echo '</p>';
+                               return false;
+                       }
</ins><span class="cx"> 
</span><span class="cx">          $this->id = (int) $file['id'];
</span><del>-               $import_data = $this->parse( $file['file'] );
</del><ins>+                // do a dry run of the parse just to get author data
+               $import_data = $this->importer->do_parse( $file['file'], true );
+
</ins><span class="cx">           if ( is_wp_error( $import_data ) ) {
</span><del>-                       echo '<p><strong>' . __( 'Sorry, there has been an error.', 'wordpress-importer' ) . '</strong><br />';
</del><ins>+                        /* @var $import_data WP_Error */
+                       if ( 'import_wxr_version_error' == $import_data->get_error_code() ) {
+                               echo '<div class="error"><p><strong>';
+                               printf(
+                                               __(
+                                                               'This WXR file (version %s) may not be supported by this version of the importer. Please consider updating.',
+                                                               'wordpress-importer' ),
+                                               esc_html( $import_data->get_error_data() ) );
+                               echo '</strong></p></div>';
+                       }
+                       echo '<p><strong>' . __( 'Sorry, there has been an error.',
+                                       'wordpress-importer' ) . '</strong><br />';
</ins><span class="cx">                   echo esc_html( $import_data->get_error_message() ) . '</p>';
</span><span class="cx">                  return false;
</span><span class="cx">          }
</span><span class="cx"> 
</span><del>-               $this->version = $import_data['version'];
-               if ( $this->version > $this->max_wxr_version ) {
-                       echo '<div class="error"><p><strong>';
-                       printf( __( 'This WXR file (version %s) may not be supported by this version of the importer. Please consider updating.', 'wordpress-importer' ), esc_html($import_data['version']) );
-                       echo '</strong></p></div>';
-               }
-
-               $this->get_authors_from_import( $import_data );
-
</del><span class="cx">           return true;
</span><span class="cx">  }
</span><span class="cx"> 
</span><span class="cx">  /**
</span><del>-        * Retrieve authors from parsed WXR data
-        *
-        * Uses the provided author information from WXR 1.1 files
-        * or extracts info from each post for WXR 1.0 files
-        *
-        * @param array $import_data Data returned by a WXR parser
-        */
-       function get_authors_from_import( $import_data ) {
-               if ( ! empty( $import_data['authors'] ) ) {
-                       $this->authors = $import_data['authors'];
-               // no author information, grab it from the posts
-               } else {
-                       foreach ( $import_data['posts'] as $post ) {
-                               $login = sanitize_user( $post['post_author'], true );
-                               if ( empty( $login ) ) {
-                                       printf( __( 'Failed to import author %s. Their posts will be attributed to the current user.', 'wordpress-importer' ), esc_html( $post['post_author'] ) );
-                                       echo '<br />';
-                                       continue;
-                               }
-
-                               if ( ! isset($this->authors[$login]) )
-                                       $this->authors[$login] = array(
-                                               'author_login' => $login,
-                                               'author_display_name' => $post['post_author']
-                                       );
-                       }
-               }
-       }
-
-       /**
</del><span class="cx">    * Display pre-import options, author importing/mapping and option to
</span><span class="cx">   * fetch attachments
</span><span class="cx">   */
</span><span class="cx">  function import_options() {
</span><ins>+               $authors = $this->importer->get_authors();
</ins><span class="cx">           $j = 0;
</span><ins>+
+               if(is_wp_error($authors)) {
+                       echo '<p><strong>' . __( 'Sorry, there has been an error.',
+                           'wordpress-importer' ) . '</strong><br />';
+                       echo esc_html( $authors->get_error_message() ) . '</p>';
+               }
</ins><span class="cx"> ?>
</span><span class="cx"> <form
</span><span class="cx">  action="<?php echo admin_url( 'admin.php?import=wordpress&amp;step=2' ); ?>"
</span><span class="lines">@@ -232,20 +229,20 @@
</span><span class="cx">  <?php wp_nonce_field( 'import-wordpress' ); ?>
</span><span class="cx">  <input type="hidden" name="import_id" value="<?php echo $this->id; ?>" />
</span><span class="cx"> 
</span><del>-<?php if ( ! empty( $this->authors ) ) : ?>
</del><ins>+<?php if ( ! empty( $authors ) && !is_wp_error($authors) ) : ?>
</ins><span class="cx">   <h3><?php _e( 'Assign Authors', 'wordpress-importer' ); ?></h3>
</span><span class="cx">  <p><?php _e( 'To make it easier for you to edit and save the imported content, you may want to reassign the author of the imported item to an existing user of this site. For example, you may want to import all the entries as <code>admin</code>s entries.', 'wordpress-importer' ); ?></p>
</span><del>-<?php if ( $this->allow_create_users() ) : ?>
</del><ins>+<?php if ( $this->importer->is_allowed_user_creation() ) : ?>
</ins><span class="cx">   <p><?php printf( __( 'If a new user is created by WordPress, a new password will be randomly generated and the new user&#8217;s role will be set as %s. Manually changing the new user&#8217;s details will be necessary.', 'wordpress-importer' ), esc_html( get_option('default_role') ) ); ?></p>
</span><span class="cx"> <?php endif; ?>
</span><span class="cx">  <ol id="authors">
</span><del>-<?php foreach ( $this->authors as $author ) : ?>
</del><ins>+<?php foreach ( $authors as $author ) : ?>
</ins><span class="cx">           <li><?php $this->author_select( $j++, $author ); ?></li>
</span><span class="cx"> <?php endforeach; ?>
</span><span class="cx">  </ol>
</span><span class="cx"> <?php endif; ?>
</span><span class="cx"> 
</span><del>-<?php if ( $this->allow_fetch_attachments() ) : ?>
</del><ins>+<?php if ( $this->importer->is_allowed_attachment_fetch() ) : ?>
</ins><span class="cx">   <h3><?php _e( 'Import Attachments', 'wordpress-importer' ); ?></h3>
</span><span class="cx">  <p>
</span><span class="cx">          <input type="checkbox" value="1" name="fetch_attachments"
</span><span class="lines">@@ -269,17 +266,19 @@
</span><span class="cx">   * @param array $author Author information, e.g. login, display name, email
</span><span class="cx">   */
</span><span class="cx">  function author_select( $n, $author ) {
</span><ins>+               $version = $this->importer->get_version();
+               $create_users = $this->importer->is_allowed_user_creation();
+
</ins><span class="cx">           _e( 'Import author:', 'wordpress-importer' );
</span><span class="cx">          echo ' <strong>' . esc_html( $author['author_display_name'] );
</span><del>-               if ( $this->version != '1.0' ) echo ' (' . esc_html( $author['author_login'] ) . ')';
</del><ins>+                if ( $version != 1.0 ) echo ' (' . esc_html( $author['author_login'] ) . ')';
</ins><span class="cx">           echo '</strong><br />';
</span><span class="cx"> 
</span><del>-               if ( $this->version != '1.0' )
</del><ins>+                if ( $version != 1.0 )
</ins><span class="cx">                   echo '<div style="margin-left:18px">';
</span><span class="cx"> 
</span><del>-               $create_users = $this->allow_create_users();
</del><span class="cx">           if ( $create_users ) {
</span><del>-                       if ( $this->version != '1.0' ) {
</del><ins>+                        if ( $version != 1.0 ) {
</ins><span class="cx">                           _e( 'or create new user with login name:', 'wordpress-importer' );
</span><span class="cx">                          $value = '';
</span><span class="cx">                  } else {
</span><span class="lines">@@ -290,14 +289,14 @@
</span><span class="cx">                  echo ' <input type="text" name="user_new['.$n.']" value="'. $value .'" /><br />';
</span><span class="cx">          }
</span><span class="cx"> 
</span><del>-               if ( ! $create_users && $this->version == '1.0' )
</del><ins>+                if ( ! $create_users && $version == 1.0 )
</ins><span class="cx">                   _e( 'assign posts to an existing user:', 'wordpress-importer' );
</span><span class="cx">          else
</span><span class="cx">                  _e( 'or assign posts to an existing user:', 'wordpress-importer' );
</span><span class="cx">          wp_dropdown_users( array( 'name' => "user_map[$n]", 'multi' => true, 'show_option_all' => __( '- Select -', 'wordpress-importer' ) ) );
</span><span class="cx">          echo '<input type="hidden" name="imported_authors['.$n.']" value="' . esc_attr( $author['author_login'] ) . '" />';
</span><span class="cx"> 
</span><del>-               if ( $this->version != '1.0' )
</del><ins>+                if ( $version != 1.0 )
</ins><span class="cx">                   echo '</div>';
</span><span class="cx">  }
</span><span class="cx"> 
</span><span class="lines">@@ -333,6 +332,32 @@
</span><span class="cx">          echo '</div>';
</span><span class="cx">  }
</span><span class="cx"> 
</span><ins>+       function status() {
+               // since the instance in this class should have loaded its variables
+               // from the options, we SHOULD be able to query it for status
+               echo '<h3>Import Status</h3>';
+
+               echo '<pre>';
+               echo 'Time left? ';
+               var_dump($this->importer->have_time());
+               echo "\n";
+               var_dump(get_option(get_class($this->importer)));
+               echo '</pre>';
+
+               $error = $this->importer->get_error();
+               $warnings = $this->importer->get_warnings();
+               foreach ( $warnings as $warning ) {
+                       /* @var $warning WP_Error */
+                       print_r( $warning );
+               }
+
+               // if done, run the import_end() cleanup; note that this will wipe
+               // any error and warning data, so we need to get all that first (above)
+               if ( 'finish' == $this->importer->get_step() || $_GET['abort'] ) {
+                       $this->import_end();
+               }
+       }
+
</ins><span class="cx">   /**
</span><span class="cx">   * Added to http_request_timeout filter to force timeout at 60 seconds during import
</span><span class="cx">   * @return int 60
</span><span class="lines">@@ -342,7 +367,6 @@
</span><span class="cx">  }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-} // class_exists( 'WP_Importer' )
</del><span class="cx"> function wordpress_importer_init() {
</span><span class="cx">  load_plugin_textdomain( 'wordpress-importer', false,
</span><span class="cx">                  dirname( plugin_basename( __FILE__ ) ) . '/languages' );
</span><span class="lines">@@ -361,4 +385,4 @@
</span><span class="cx">                                  $GLOBALS['wp_import'],
</span><span class="cx">                                  'dispatch' ) );
</span><span class="cx"> }
</span><del>-add_action( 'admin_init', 'wordpress_importer_init' );
</del><ins>+add_action( 'init', 'wordpress_importer_init' );
</ins></span></pre>
</div>
</div>

</body>
</html>