示例#1
0
    /**
     * The plugin sink for the auth_ajax_wp_import_comments hook.
     * Responds via authenticated ajax to requests for comment importing.
     *
     * @param AjaxHandler $handler The handler that handled the request, contains $_POST info
     */
    public function action_auth_ajax_wp_import_comments($handler)
    {
        $valid_fields = array('db_name', 'db_host', 'db_user', 'db_pass', 'db_prefix', 'commentindex', 'category_import', 'utw_import');
        $inputs = array_intersect_key($_POST->getArrayCopy(), array_flip($valid_fields));
        extract($inputs);
        $wpdb = $this->wp_connect($db_host, $db_name, $db_user, $db_pass, $db_prefix);
        if ($wpdb) {
            if (!DB::in_transaction()) {
                DB::begin_transaction();
            }
            $commentcount = $wpdb->get_value("SELECT count( comment_ID ) FROM {$db_prefix}comments;");
            $min = $commentindex * IMPORT_BATCH + 1;
            $max = min(($commentindex + 1) * IMPORT_BATCH, $commentcount);
            echo "<p>Importing comments {$min}-{$max} of {$commentcount}.</p>";
            $postinfo = DB::table('postinfo');
            $post_info = DB::get_results("SELECT post_id, value FROM {$postinfo} WHERE name= 'wp_id';");
            foreach ($post_info as $info) {
                $post_map[$info->value] = $info->post_id;
            }
            $comments = $wpdb->get_results("\n\t\t\t\tSELECT\n\t\t\t\tcomment_content as content,\n\t\t\t\tcomment_author as name,\n\t\t\t\tcomment_author_email as email,\n\t\t\t\tcomment_author_url as url,\n\t\t\t\tINET_ATON( comment_author_IP ) as ip,\n\t\t\t \tcomment_approved as status,\n\t\t\t\tcomment_date as date,\n\t\t\t\tcomment_type as type,\n\t\t\t\tID as wp_post_id\n\t\t\t\tFROM {$db_prefix}comments\n\t\t\t\tINNER JOIN\n\t\t\t\t{$db_prefix}posts on ( {$db_prefix}posts.ID= {$db_prefix}comments.comment_post_ID )\n\t\t\t\tLIMIT {$min}, " . IMPORT_BATCH, array(), 'Comment');
            foreach ($comments as $comment) {
                switch ($comment->type) {
                    case 'pingback':
                        $comment->type = Comment::PINGBACK;
                        break;
                    case 'trackback':
                        $comment->type = Comment::TRACKBACK;
                        break;
                    default:
                        $comment->type = Comment::COMMENT;
                }
                $comment->content = MultiByte::convert_encoding($comment->content);
                $comment->name = MultiByte::convert_encoding($comment->name);
                $carray = $comment->to_array();
                if ($carray['ip'] == '') {
                    $carray['ip'] = 0;
                }
                switch ($carray['status']) {
                    case '0':
                        $carray['status'] = Comment::STATUS_UNAPPROVED;
                        break;
                    case '1':
                        $carray['status'] = Comment::STATUS_APPROVED;
                        break;
                    case 'spam':
                        $carray['status'] = Comment::STATUS_SPAM;
                        break;
                }
                if (isset($post_map[$carray['wp_post_id']])) {
                    $carray['post_id'] = $post_map[$carray['wp_post_id']];
                    unset($carray['wp_post_id']);
                    $c = new Comment($carray);
                    //Utils::debug( $c );
                    try {
                        $c->insert();
                    } catch (Exception $e) {
                        EventLog::log($e->getMessage(), 'err', null, null, print_r(array($c, $e), 1));
                        Session::error($e->getMessage());
                        $errors = Options::get('import_errors');
                        $errors[] = $e->getMessage();
                        Options::set('import_errors', $errors);
                    }
                }
            }
            if (DB::in_transaction()) {
                DB::commit();
            }
            if ($max < $commentcount) {
                $ajax_url = URL::get('auth_ajax', array('context' => 'wp_import_comments'));
                $commentindex++;
                $vars = Utils::addslashes(array('host' => $db_host, 'name' => $db_name, 'user' => $db_user, 'pass' => $db_pass, 'prefix' => $db_prefix));
                echo <<<WP_IMPORT_AJAX1
\t\t\t\t\t<script type="text/javascript">
\t\t\t\t\t\$( '#import_progress' ).load(
\t\t\t\t\t\t"{$ajax_url}",
\t\t\t\t\t\t{
\t\t\t\t\t\t\tdb_host: "{$vars['host']}",
\t\t\t\t\t\t\tdb_name: "{$vars['name']}",
\t\t\t\t\t\t\tdb_user: "******",
\t\t\t\t\t\t\tdb_pass: "******",
\t\t\t\t\t\t\tdb_prefix: "{$vars['prefix']}",
\t\t\t\t\t\t\tcategory_import: "{$category_import}",
\t\t\t\t\t\t\tutw_import: "{$utw_import}",
\t\t\t\t\t\t\tcommentindex: {$commentindex}
\t\t\t\t\t\t}
\t\t\t\t\t );

\t\t\t\t</script>
WP_IMPORT_AJAX1;
            } else {
                EventLog::log('Import complete from "' . $db_name . '"');
                echo '<p>' . _t('Import is complete.') . '</p>';
                $errors = Options::get('import_errors');
                if (count($errors) > 0) {
                    echo '<p>' . _t('There were errors during import:') . '</p>';
                    echo '<ul>';
                    foreach ($errors as $error) {
                        echo '<li>' . $error . '</li>';
                    }
                    echo '</ul>';
                }
            }
        } else {
            EventLog::log(sprintf(_t('Failed to import from "%s"'), $db_name), 'crit');
            Session::error($e->getMessage());
            echo '<p>' . _t('Failed to connect using the given database connection details.') . '</p>';
        }
    }
示例#2
0
    /**
     * Moves a term within the vocabulary. Returns a Term object. null parameters append the term to the end of any hierarchies.
     *
     * The MPTT operations can seem complex, but they're actually pretty simple:
     * 		1: Find our insertion point:
     * 			Either at the very end of the vocabulary, or before / after the given term
     * 		2: Create a gap at that point:
     * 			We'll bump everything at that point or after up enough to fit in the term we're moving
     * 		3: Move the term:
     * 			We know the offset between the old point and the new point, so move the range up that number of spaces.
     * 		4: Close the original gap:
     * 			Now we've got all our terms moved, but we need to bump everything back down to close the gap it left, similar to #2.
     *
     * @param Term $term The term to move.
     * @param Term|null $target_term The term to move $term before or after, or null to move it to the very end of the vocabulary.
     * @param bool $before True to move $term BEFORE $target_term, false (the default) to move $term AFTER $target_term.
     * @return Term The Term object moved
     **/
    public function move_term($term, $target_term = null, $before = false)
    {
        // We assume that the arguments passed are valid terms. Check them before calling this.
        // If there are terms in the vocabulary, work out the reference point
        if (!$this->is_empty()) {
            $source_left = $term->mptt_left;
            $source_right = $term->mptt_right;
            $range = $source_right - $source_left + 1;
            DB::begin_transaction();
            // Determine the insertion point mptt_target
            if ($target_term == null) {
                // if no target is specified, put the new term after the last term
                $mptt_target = DB::get_value('SELECT MAX(mptt_right) FROM {terms} WHERE vocabulary_id = :id', array(':id' => $this->id));
                $mptt_target = $mptt_target + 1;
                // the left is one greater than the highest right
            } else {
                // if we're putting it before
                if ($before) {
                    $mptt_target = $target_term->mptt_left;
                    // we're actually taking the place of the target term's left
                } else {
                    $mptt_target = $target_term->mptt_right + 1;
                    // we just need to start at the next number
                }
            }
            // Create space in the tree for the insertion
            $params = array('vocab_id' => $this->id, 'range' => $range, 'mptt_target' => $mptt_target);
            $res = DB::query('UPDATE {terms} SET mptt_left = mptt_left + :range WHERE vocabulary_id = :vocab_id AND mptt_left >= :mptt_target', $params);
            if (!$res) {
                DB::rollback();
                return false;
            }
            $res = DB::query('UPDATE {terms} SET mptt_right = mptt_right + :range WHERE vocabulary_id = :vocab_id AND mptt_right >= :mptt_target', $params);
            if (!$res) {
                DB::rollback();
                return false;
            }
            // if we're moving it "down" ("forward"?) in the vocabulary, we just created a gap that changed our term's left and right values
            if ($mptt_target < $source_left) {
                $source_left = $source_left + $range;
                $source_right = $source_right + $range;
            }
            // figure out how far our nodes are moving
            $offset = $mptt_target - $source_left;
            // move our lucky nodes into the space we just created
            $params = array(':offset' => $offset, ':vocab_id' => $this->id, ':source_left' => $source_left, ':source_right' => $source_right);
            $res = DB::query('
				UPDATE {terms}
				SET
					mptt_left = mptt_left + :offset,
					mptt_right = mptt_right + :offset
				WHERE
					vocabulary_id = :vocab_id AND
					mptt_left >= :source_left AND
					mptt_right <= :source_right
				', $params);
            // Close the gap in the tree created by moving those nodes out
            $params = array('range' => $range, 'vocab_id' => $this->id, 'source_left' => $source_left);
            $res = DB::query('UPDATE {terms} SET mptt_left = mptt_left - :range WHERE vocabulary_id = :vocab_id AND mptt_left > :source_left', $params);
            if (!$res) {
                DB::rollback();
                return false;
            }
            $params = array('range' => $range, 'vocab_id' => $this->id, 'source_right' => $source_right);
            $res = DB::query('UPDATE {terms} SET mptt_right = mptt_right - :range WHERE vocabulary_id = :vocab_id AND mptt_right > :source_right', $params);
            if (!$res) {
                DB::rollback();
                return false;
            }
            // Success!
            DB::commit();
            return $this->get_term($term->id);
        }
        return false;
    }
示例#3
0
 public function action_auth_ajax_wp_import_comments()
 {
     // get the values post'd in
     $inputs = $_POST->filter_keys(array('db_name', 'db_host', 'db_user', 'db_pass', 'db_prefix', 'category_import', 'import_index'));
     $inputs = $inputs->getArrayCopy();
     // make sure we have all our default values
     $inputs = array_merge($this->default_values, $inputs);
     // get the wpdb
     $wpdb = $this->wp_connect($inputs['db_host'], $inputs['db_name'], $inputs['db_user'], $inputs['db_pass']);
     // if we couldn't connect, error out
     if (!$wpdb) {
         EventLog::log(_t('Failed to import from "%s"', array($inputs['db_name'])));
         Session::error(_t('Failed to import from "%s"', array($inputs['db_name'])));
         echo '<p>' . _t('Failed to connect using the given database connection details.') . '</p>';
     }
     // we connected just fine, let's get moving!
     // begin a transaction. if we error out at any point, we want to roll back to before import began
     DB::begin_transaction();
     // fetch the number of comments from the wordpress database so we can batch things up
     $num_comments = $wpdb->get_value('select count(comment_id) from ' . $inputs['db_prefix'] . 'comments');
     // figure out the LIMIT we're at
     $min = $inputs['import_index'] * IMPORT_BATCH;
     $max = min($min + IMPORT_BATCH, $num_comments);
     // for display only
     echo '<p>' . _t('Importing comments %1$d - %2$d of %3$d.', array($min, $max, $num_comments)) . '</p>';
     // get all the imported users so we can link old comment authors to new comment authors
     $users = DB::get_results('select user_id, value from {userinfo} where name = :name', array(':name' => 'wp_id'));
     // create an easy user map of old ID -> new ID
     $user_map = array();
     foreach ($users as $info) {
         $user_map[$info->value] = $info->user_id;
     }
     // get all the imported posts so we can link old post IDs to new post IDs
     $posts = DB::get_results('select post_id, value from {postinfo} where name = :name', array(':name' => 'wp_id'));
     // create an easy post map of old ID -> new ID
     $post_map = array();
     foreach ($posts as $info) {
         $post_map[$info->value] = $info->post_id;
     }
     // get all the comment IDs we've imported so far to make sure we don't duplicate any
     $comment_map = DB::get_column('select value from {commentinfo} where name = :name', array(':name' => 'wp_id'));
     // now we're ready to start importing comments
     $comments = $wpdb->get_results('select comment_id, comment_post_id, comment_author, comment_author_email, comment_author_url, comment_author_ip, comment_date, comment_content, comment_karma, comment_approved, comment_agent, comment_type, comment_parent, user_id from ' . $inputs['db_prefix'] . 'comments order by comment_id asc limit ' . $min . ', ' . IMPORT_BATCH);
     foreach ($comments as $comment) {
         // if this post is already in the list we've imported, skip it
         if (in_array($comment->id, $comment_map)) {
             continue;
         }
         // if the post this comment belongs to is not in the list of imported posts, skip it
         if (!isset($post_map[$comment->comment_post_id])) {
             continue;
         }
         // create the new comment
         $c = new Comment(array('content' => MultiByte::convert_encoding($comment->comment_content), 'name' => MultiByte::convert_encoding($comment->comment_author), 'email' => MultiByte::convert_encoding($comment->comment_author_email), 'url' => MultiByte::convert_encoding($comment->comment_author_url), 'date' => HabariDateTime::date_create($comment->comment_date), 'post_id' => $post_map[$comment->comment_post_id]));
         // figure out the comment type
         switch ($comment->comment_type) {
             case 'pingback':
                 $c->type = Comment::type('pingback');
                 break;
             case 'trackback':
                 $c->type = Comment::type('trackback');
                 break;
             default:
             case 'comment':
                 $c->type = Comment::type('comment');
                 break;
         }
         // figure out the comment status
         switch ($comment->comment_approved) {
             case '1':
                 $c->status = Comment::status('approved');
                 break;
             case '':
             case '0':
                 $c->status = Comment::status('unapproved');
                 break;
             case 'spam':
                 $c->status = Comment::status('spam');
                 break;
             default:
                 // Comment::status() returns false if it doesn't recognize the status type
                 $status = Comment::status($comment->comment_status);
                 // store in a temp value because if you try and set ->status to an invalid value the Comment class freaks
                 if ($status == false) {
                     // we're not importing statuses we don't recognize - continue 2 to break out of the switch and the loop and continue to the next comment
                     continue 2;
                 } else {
                     $c->status = $status;
                 }
                 break;
         }
         // save the old comment ID in info
         $c->info->wp_id = $comment->comment_id;
         // save the old post ID in info
         $c->info->wp_post_id = $comment->comment_post_id;
         // save the old comment karma - but only if it is something
         if ($comment->comment_karma != '0') {
             $c->info->wp_karma = $comment->comment_karma;
         }
         // save the old comment user agent - but only if it is something
         if ($comment->comment_agent != '') {
             $c->info->wp_agent = $comment->comment_agent;
         }
         // now that we've got all the pieces in place, save the comment
         try {
             $c->insert();
         } catch (Exception $e) {
             EventLog::log($e->getMessage(), 'err');
             echo '<p class="error">' . _t('There was an error importing comment ID %d. See the EventLog for the error message.', array($comment->comment_id));
             echo '<p>' . _t('Rolling back changes&hellip;') . '</p>';
             // rollback all changes before we return so the import hasn't changed anything yet
             DB::rollback();
             // and return so they don't get AJAX to send them on to the next step
             return false;
         }
     }
     // if we've finished without an error, commit the import
     DB::commit();
     if ($max < $num_comments) {
         // if there are more posts to import
         // get the next ajax url
         $ajax_url = URL::get('auth_ajax', array('context' => 'wp_import_comments'));
         // bump the import index by one so we get a new batch next time
         $inputs['import_index']++;
     } else {
         // display the completed message!
         EventLog::log(_t('Import completed from "%s"', array($inputs['db_name'])));
         echo '<p>' . _t('Import is complete.') . '</p>';
         return;
     }
     // and spit out ajax to send them to the next step - posts!
     echo $this->get_ajax($ajax_url, $inputs);
 }
示例#4
0
 /**
  * Attempts to install the database.  Returns the result of
  * the installation, adding errors to the theme if any
  * occur
  *
  * @return bool result of installation
  */
 private function install_db()
 {
     $db_host = $this->handler_vars['db_host'];
     $db_type = $this->handler_vars['db_type'];
     $db_schema = $this->handler_vars['db_schema'];
     $db_user = $this->handler_vars['db_user'];
     $db_pass = $this->handler_vars['db_pass'];
     switch ($db_type) {
         case 'mysql':
         case 'pgsql':
             // MySQL & PostgreSQL requires specific connection information
             if (empty($db_user)) {
                 $this->theme->assign('form_errors', array("{$db_type}_db_user" => _t('User is required.')));
                 return false;
             }
             if (empty($db_schema)) {
                 $this->theme->assign('form_errors', array("{$db_type}_db_schema" => _t('Name for database is required.')));
                 return false;
             }
             if (empty($db_host)) {
                 $this->theme->assign('form_errors', array("{$db_type}_db_host" => _t('Host is required.')));
                 return false;
             }
             break;
         case 'sqlite':
             // If this is a SQLite database, let's check that the file
             // exists and that we can access it.
             if (!$this->check_sqlite()) {
                 return false;
             }
             break;
     }
     if (isset($this->handler_vars['table_prefix'])) {
         // store prefix in the Config singleton so DatabaseConnection can access it
         Config::set('db_connection', array('prefix' => $this->handler_vars['table_prefix']));
     }
     if (!$this->connect_to_existing_db()) {
         $this->theme->assign('form_errors', array("{$db_type}_db_user" => _t('Problem connecting to supplied database credentials')));
         return false;
     }
     DB::begin_transaction();
     /* Let's install the DB tables now. */
     $create_table_queries = $this->get_create_table_queries($this->handler_vars['db_type'], $this->handler_vars['table_prefix'], $this->handler_vars['db_schema']);
     DB::clear_errors();
     DB::dbdelta($create_table_queries, true, true, true);
     if (DB::has_errors()) {
         $error = DB::get_last_error();
         $this->theme->assign('form_errors', array('db_host' => _t('Could not create schema tables&hellip; %s', array($error['message']))));
         DB::rollback();
         return false;
     }
     // Cool.  DB installed. Create the default options
     // but check first, to make sure
     if (!Options::get('installed')) {
         if (!$this->create_default_options()) {
             $this->theme->assign('form_errors', array('options' => _t('Problem creating default options')));
             DB::rollback();
             return false;
         }
     }
     // Create the Tags vocabulary
     if (!$this->create_tags_vocabulary()) {
         $this->theme->assign('form_errors', array('options' => _t('Problem creating tags vocabulary')));
         DB::rollback();
         return false;
     }
     // Create the standard post types and statuses
     if (!$this->create_base_post_types()) {
         $this->theme->assign('form_errors', array('options' => _t('Problem creating base post types')));
         DB::rollback();
         return false;
     }
     if (!$this->create_base_comment_types()) {
         $this->theme->assign('form_errors', array('options' => _t('Problem creating base comment types and statuses')));
         DB::rollback();
         return false;
     }
     // Let's setup the admin user and group now.
     // But first, let's make sure that no users exist
     $all_users = Users::get_all();
     if (count($all_users) < 1) {
         $user = $this->create_admin_user();
         if (!$user) {
             $this->theme->assign('form_errors', array('admin_user' => _t('Problem creating admin user.')));
             DB::rollback();
             return false;
         }
         $admin_group = $this->create_admin_group($user);
         if (!$admin_group) {
             $this->theme->assign('form_errors', array('admin_user' => _t('Problem creating admin group.')));
             DB::rollback();
             return false;
         }
         // create default tokens
         ACL::rebuild_permissions($user);
     }
     // create a first post, if none exists
     if (!Posts::get(array('count' => 1))) {
         if (!$this->create_first_post()) {
             $this->theme->assign('form_errors', array('post' => _t('Problem creating first post.')));
             DB::rollback();
             return false;
         }
     }
     /* Post::save_tags() closes transaction, until we fix that, check and reconnect if needed */
     if (!DB::in_transaction()) {
         DB::begin_transaction();
     }
     /* Store current DB version so we don't immediately run dbdelta. */
     Version::save_dbversion();
     /* Ready to roll. */
     DB::commit();
     return true;
 }
示例#5
0
    /**
     * Moves a term within the vocabulary. Returns a Term object. null parameters append the term to the end of any hierarchies.
     * @return Term The Term object moved
     **/
    public function move_term($term, $target_term = null, $before = FALSE)
    {
        // We assume that the arguments passed are valid terms. Check them before calling this.
        // If there are terms in the vocabulary, work out the reference point
        if (!$this->is_empty()) {
            $source_left = $term->mptt_left;
            $source_right = $term->mptt_right;
            $range = $source_right - $source_left + 1;
            $nodes_moving = $range / 2;
            // parent and descendants
            DB::begin_transaction();
            // Move the source nodes out of the way by making mptt_left and mptt_right negative
            $source_to_temp = $source_right + 1;
            // move the terms so that the rightmost one's mptt_right is -1
            $params = array('displacement' => $source_to_temp, 'vocab_id' => $this->id, 'range_left' => $source_left, 'range_right' => $source_right);
            $res = DB::query('
				UPDATE {terms} 
				SET 
					mptt_left = mptt_left - :displacement, 
					mptt_right = mptt_right - :displacement 
				WHERE 
					vocabulary_id = :vocab_id
					AND mptt_left BETWEEN :range_left AND :range_right
				', $params);
            if (!$res) {
                DB::rollback();
                return FALSE;
            }
            // Close the gap in the tree created by moving those nodes out
            $params = array('range' => $range, 'vocab_id' => $this->id, 'source_left' => $source_left);
            $res = DB::query('UPDATE {terms} SET mptt_left=mptt_left-:range WHERE vocabulary_id=:vocab_id AND mptt_left > :source_left', $params);
            if (!$res) {
                DB::rollback();
                return FALSE;
            }
            $res = DB::query('UPDATE {terms} SET mptt_right=mptt_right-:range WHERE vocabulary_id=:vocab_id AND mptt_right > :source_left', $params);
            if (!$res) {
                DB::rollback();
                return FALSE;
            }
            // Determine the insertion point mptt_target
            if ($this->hierarchical) {
                if (null == $target_term) {
                    // If no target is specified, put the new term after the last term
                    $mptt_target = DB::get_value('SELECT MAX(mptt_right) FROM {terms} WHERE vocabulary_id=?', array($this->id)) + 1;
                } else {
                    if (FALSE == $before) {
                        $mptt_target = DB::get_value('SELECT mptt_right FROM {terms} WHERE vocabulary_id=? AND id = ?', array($this->id, $target_term->id));
                    } else {
                        $mptt_target = DB::get_value('SELECT mptt_left FROM {terms} WHERE vocabulary_id=? AND id = ?', array($this->id, $target_term->id));
                    }
                }
            } else {
                // vocabulary is not hierarchical
                if (FALSE != $before) {
                    $mptt_target = DB::get_value('SELECT mptt_left FROM {terms} WHERE vocabulary_id=? AND id = ?', array($this->id, $target_term->id));
                } else {
                    $mptt_target = DB::get_value('SELECT MAX(mptt_right) FROM {terms} WHERE vocabulary_id=?', array($this->id)) + 1;
                }
            }
            $temp_left = $source_left - $source_to_temp;
            $temp_to_target = $mptt_target - $temp_left;
            // Create space in the tree for the insertion
            $params = array('vocab_id' => $this->id, 'range' => $range, 'mptt_target' => $mptt_target);
            $res = DB::query('UPDATE {terms} SET mptt_left=mptt_left+:range WHERE vocabulary_id=:vocab_id AND mptt_left >= :mptt_target', $params);
            if (!$res) {
                DB::rollback();
                return FALSE;
            }
            $res = DB::query('UPDATE {terms} SET mptt_right=mptt_right+:range WHERE vocabulary_id=:vocab_id AND mptt_right >= :mptt_target', $params);
            if (!$res) {
                DB::rollback();
                return FALSE;
            }
            // Move the temp nodes into the space created for them
            $params = array('vocab_id' => $this->id, 'temp_to_target' => $temp_to_target);
            $res = DB::query('UPDATE {terms} SET mptt_left=mptt_left+:temp_to_target WHERE vocabulary_id=:vocab_id AND mptt_left < 0', $params);
            if (!$res) {
                DB::rollback();
                return FALSE;
            }
            $res = DB::query('UPDATE {terms} SET mptt_right=mptt_right+:temp_to_target WHERE vocabulary_id=:vocab_id AND mptt_right < 0', $params);
            if (!$res) {
                DB::rollback();
                return FALSE;
            }
            // Success!
            DB::commit();
            // @todo: need to return the updated term
            return $term;
        }
        return FALSE;
    }
示例#6
0
 private function make_post($user, $time)
 {
     // start a transaction, so if we die due to a timeout (like in meller's php-cgi environment) we don't end up with broken posts and post info
     DB::begin_transaction();
     $post = Post::create(array('title' => $this->get_post_title(), 'content' => $this->get_post_content(), 'user_id' => $user->id, 'status' => $this->get_post_status(), 'content_type' => Post::type('entry'), 'tags' => $this->get_post_tags(), 'pubdate' => DateTime::date_create($time)));
     $post->info->lipsum = true;
     $post->info->commit();
     // how many comments should we create?
     $comments = mt_rand(0, Options::get('lipsum__num_comments'));
     // the initial comment time we'll start from - a little after the post was created
     $comment_time = $time + 160;
     for ($i = 0; $i < $comments; $i++) {
         // figure out the comment time for this one
         $comment_time = $comment_time + mt_rand(3600, 3600 * 24);
         // between 1 hour and 24 hours after the last comment
         $this->make_comment($post, $comment_time);
     }
     // commit the transaction, we're done!
     DB::commit();
 }
    /**
     * The plugin sink for the auth_ajax_chyrp_import_posts hook.
     * Responds via authenticated ajax to requests for post importing.
     *
     * @param AjaxHandler $handler The handler that handled the request, contains $_POST info
     */
    public function action_auth_ajax_chyrp_import_posts($handler)
    {
        $inputs = $_POST->filter_keys('db_type', 'db_name', 'db_host', 'db_user', 'db_pass', 'postindex');
        foreach ($inputs as $key => $value) {
            ${$key} = $value;
        }
        $connect_string = $this->get_connect_string($db_type, $db_host, $db_name);
        $db = $this->chryp_connect($connect_string, $db_user, $db_pass);
        if ($db) {
            DB::begin_transaction();
            $postcount = $db->get_value("SELECT count(id) FROM posts;");
            $min = $postindex * IMPORT_BATCH + ($postindex == 0 ? 0 : 1);
            $max = min(($postindex + 1) * IMPORT_BATCH, $postcount);
            // old_id was set when we imported the users
            $user_map = array();
            $user_info = DB::get_results("SELECT user_id, value FROM {userinfo} WHERE name='old_id';");
            foreach ($user_info as $info) {
                $user_map[$info->value] = $info->user_id;
            }
            // Posts
            // id INTEGER PRIMARY KEY AUTOINCREMENT,
            // feather VARCHAR(32) DEFAULT '',
            // clean VARCHAR(128) DEFAULT '',
            // url VARCHAR(128) DEFAULT '',
            // pinned BOOLEAN DEFAULT FALSE,
            // status VARCHAR(32) DEFAULT 'public',
            // user_id INTEGER DEFAULT 0,
            // created_at DATETIME DEFAULT NULL,
            // updated_at DATETIME DEFAULT NULL
            //
            // Post attributes
            // post_id INTEGER NOT NULL ,
            // name VARCHAR(100) DEFAULT '',
            // value LONGTEXT,
            echo "<p>Importing posts {$min}-{$max} of {$postcount}.</p>";
            $posts = $db->get_results("\r\n\t\t\t\tSELECT\r\n\t\t\t\t\tattr_body.value as content,\r\n\t\t\t\t\tid,\r\n\t\t\t\t\tattr_title.value as title,\r\n\t\t\t\t\tuser_id,\r\n\t\t\t\t\tcreated_at as pubdate,\r\n\t\t\t\t\tupdated_at as updated,\r\n\t\t\t\t\tupdated_at as modified,\r\n\t\t\t\t\tstatus\r\n\t\t\t\tFROM posts\r\n\t\t\t\tINNER JOIN post_attributes attr_title ON posts.id = attr_title.post_id AND attr_title.name = 'title'\r\n\t\t\t\tINNER JOIN post_attributes attr_body ON posts.id = attr_body.post_id AND attr_body.name = 'body'\r\n\t\t\t\tORDER BY id DESC\r\n\t\t\t\tLIMIT {$min}, " . IMPORT_BATCH, array(), 'Post');
            $post_map = DB::get_column("SELECT value FROM {postinfo} WHERE name='old_id';");
            foreach ($posts as $post) {
                if (in_array($post->id, $post_map)) {
                    continue;
                }
                $post_array = $post->to_array();
                $post_array['content_type'] = Post::type('entry');
                $p = new Post($post_array);
                $p->slug = $post->slug;
                if (isset($user_map[$p->user_id])) {
                    $p->user_id = $user_map[$p->user_id];
                } else {
                    $errors = Options::get('import_errors');
                    $errors[] = _t('Post author id %s was not found in the external database, assigning post "%s" (external post id #%d) to current user.', array($p->user_id, $p->title, $post_array['id']));
                    Options::set('import_errors', $errors);
                    $p->user_id = User::identify()->id;
                }
                $p->guid = $p->guid;
                // Looks fishy, but actually causes the guid to be set.
                $p->info->old_id = $post_array['id'];
                // Store the old post id in the post_info table for later
                try {
                    $p->insert();
                    $p->updated = $post_array['updated'];
                    $p->update();
                } catch (Exception $e) {
                    EventLog::log($e->getMessage(), 'err', null, null, print_r(array($p, $e), 1));
                    Session::error($e->getMessage());
                    $errors = Options::get('import_errors');
                    $errors[] = $p->title . ' : ' . $e->getMessage();
                    Options::set('import_errors', $errors);
                }
            }
            if (DB::in_transaction()) {
                DB::commit();
            }
            if ($max < $postcount) {
                $ajax_url = URL::get('auth_ajax', array('context' => 'chyrp_import_posts'));
                $postindex++;
                $vars = Utils::addslashes(array('host' => $db_host, 'name' => $db_name, 'user' => $db_user, 'pass' => $db_pass));
                echo <<<IMPORT_POSTS
\t\t\t\t\t<script type="text/javascript">
\t\t\t\t\t\$( '#import_progress' ).load(
\t\t\t\t\t\t"{$ajax_url}",
\t\t\t\t\t\t{
\t\t\t\t\t\t\tdb_type: "{$db_type}",
\t\t\t\t\t\t\tdb_host: "{$vars['host']}",
\t\t\t\t\t\t\tdb_name: "{$vars['name']}",
\t\t\t\t\t\t\tdb_user: "******",
\t\t\t\t\t\t\tdb_pass: "******",
\t\t\t\t\t\t\tpostindex: {$postindex}
\t\t\t\t\t\t}
\t\t\t\t\t);

\t\t\t\t</script>
IMPORT_POSTS;
            } else {
                EventLog::log('Import complete from "' . $db_name . '"');
                echo '<p>' . _t('Import is complete.') . '</p>';
                $errors = Options::get('import_errors');
                if (count($errors) > 0) {
                    echo '<p>' . _t('There were errors during import:') . '</p>';
                    echo '<ul>';
                    foreach ($errors as $error) {
                        echo '<li>' . $error . '</li>';
                    }
                    echo '</ul>';
                }
            }
        } else {
            EventLog::log(sprintf(_t('Failed to import from "%s"'), $db_name), 'crit');
            Session::error($e->getMessage());
            echo '<p>' . _t('The database connection details have failed to connect.') . '</p>';
        }
    }
 /**
  * The plugin sink for the auth_ajax_hab_import_comments hook.
  * Responds via authenticated ajax to requests for comment importing.
  *
  * @param AjaxHandler $handler The handler that handled the request, contains $_POST info
  */
 public function action_auth_ajax_hab_import_comments($handler)
 {
     $inputs = $_POST->filter_keys('db_type', 'db_name', 'db_host', 'db_user', 'db_pass', 'db_prefix', 'commentindex', 'tag_import');
     $inputs = $inputs->getArrayCopy($inputs);
     $inputs = array_merge($this->default_values, $inputs);
     $connect_string = $this->get_connect_string($inputs['db_type'], $inputs['db_host'], $inputs['db_name']);
     $db = $this->hab_connect($connect_string, $inputs['db_user'], $inputs['db_pass']);
     if (!$db) {
         EventLog::log(sprintf(_t('Failed to import from "%s"'), $inputs['db_name']), 'crit');
         Session::error($e->getMessage());
         echo '<p>' . _t('Failed to connect using the given database connection details.') . '</p>';
     }
     DB::begin_transaction();
     $commentcount = $db->get_value("SELECT count( id ) FROM {$inputs['db_prefix']}comments;");
     $min = $inputs['import_index'] * IMPORT_BATCH + ($inputs['import_index'] == 0 ? 0 : 1);
     $max = min(($inputs['import_index'] + 1) * IMPORT_BATCH, $commentcount);
     echo "<p>Importing comments {$min}-{$max} of {$commentcount}.</p>";
     $post_info = DB::get_results("SELECT post_id, value FROM {$inputs['db_prefix']}postinfo WHERE name= 'old_id';");
     foreach ($post_info as $info) {
         $post_map[$info->value] = $info->post_id;
     }
     $comments = $db->get_results("\r\n\t\t\tSELECT\r\n\t\t\tc.id,\r\n\t\t\tc.content,\r\n\t\t\tc.name,\r\n\t\t\tc.email,\r\n\t\t\tc.url,\r\n\t\t\tc.ip,\r\n\t\t\tc.status,\r\n\t\t\tc.date,\r\n\t\t\tc.type,\r\n\t\t\tc.post_id as old_post_id\r\n\t\t\tFROM {$inputs['db_prefix']}comments c\r\n\t\t\tINNER JOIN\r\n\t\t\t{$inputs['db_prefix']}posts on {$inputs['db_prefix']}posts.id = c.post_id\r\n\t\t\tLIMIT {$min}, " . IMPORT_BATCH, array(), 'Comment');
     foreach ($comments as $comment) {
         $carray = $comment->to_array();
         if (isset($post_map[$carray['old_post_id']])) {
             $carray['post_id'] = $post_map[$carray['old_post_id']];
             unset($carray['old_post_id']);
             $c = new Comment($carray);
             $infos = $db->get_results("SELECT name, value, type FROM {$inputs['db_prefix']}commentinfo WHERE comment_id = ?", array($carray['id']));
             foreach ($infos as $info) {
                 $fields = $info->get_url_args();
                 if ($fields['type'] == 1) {
                     $fields['value'] = unserialize($fields['value']);
                 }
                 $c->info->{$fields}['name'] = $fields['value'];
             }
             try {
                 $c->insert();
             } catch (Exception $e) {
                 EventLog::log($e->getMessage(), 'err', null, null, print_r(array($c, $e), 1));
                 Session::error($e->getMessage());
                 $errors = Options::get('import_errors');
                 $errors[] = $e->getMessage();
                 Options::set('import_errors', $errors);
             }
         }
     }
     if (DB::in_transaction()) {
         DB::commit();
     }
     if ($max < $commentcount) {
         $ajax_url = URL::get('auth_ajax', array('context' => 'hab_import_comments'));
         $inputs['import_index']++;
         echo $this->get_ajax($ajax_url, $inputs);
     } else {
         EventLog::log('Import complete from "' . $inputs['db_name'] . '"');
         echo '<p>' . _t('Import is complete.') . '</p>';
         $errors = Options::get('import_errors');
         if (count($errors) > 0) {
             echo '<p>' . _t('There were errors during import:') . '</p>';
             echo '<ul>';
             foreach ($errors as $error) {
                 echo '<li>' . $error . '</li>';
             }
             echo '</ul>';
         }
     }
 }