/** * 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>'; } }
/** * 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; }
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…') . '</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); }
/** * 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… %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; }
/** * 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; }
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>'; } } }