public function execute(array $deferred, array $data, $targetRunTime, &$status)
 {
     $data = array_merge(array('contentType' => '', 'contentIds' => false), $data);
     $status = sprintf('Search Index (Partial)');
     if (!$data['contentType'] || !$data['contentIds'] || !is_array($data['contentIds'])) {
         return false;
     }
     $limitTime = $targetRunTime > 0;
     do {
         $s = microtime(true);
         $i = 0;
         $contentIds = array();
         foreach ($data['contentIds'] as $key => $id) {
             $contentIds[] = $id;
             unset($data['contentIds'][$key]);
             if (++$i >= 10) {
                 break;
             }
         }
         $indexer = new XenForo_Search_Indexer();
         $indexer->quickIndex($data['contentType'], $contentIds);
         $targetRunTime -= microtime(true) - $s;
     } while ((!$limitTime || $targetRunTime > 0) && $data['contentIds']);
     if (!$data['contentIds']) {
         return false;
     }
     return $data;
 }
Example #2
0
    /**
     * Merge multiple threads into a single thread
     *
     * @param array $threads
     * @param integer $targetThreadId
     * @param array $options
     *
     * @return boolean|array False if failure, otherwise thread array of merged thread
     */
    public function mergeThreads(array $threads, $targetThreadId, array $options = array())
    {
        if (!isset($threads[$targetThreadId])) {
            return false;
        }
        $targetThread = $threads[$targetThreadId];
        unset($threads[$targetThreadId]);
        $mergeFromThreadIds = array_keys($threads);
        if (!$mergeFromThreadIds) {
            return false;
        }
        $options = array_merge(array('redirect' => false, 'redirectExpiry' => 0), $options);
        $postModel = $this->_getPostModel();
        $db = $this->_getDb();
        $movePosts = $this->fetchAllKeyed('
			SELECT post_id, thread_id, user_id, message_state
			FROM xf_post
			WHERE thread_id IN (' . $db->quote($mergeFromThreadIds) . ')
		', 'post_id');
        $movePostIds = array_keys($movePosts);
        XenForo_Db::beginTransaction($db);
        $db->update('xf_post', array('thread_id' => $targetThreadId), 'post_id IN (' . $db->quote($movePostIds) . ')');
        $newCounters = $postModel->recalculatePostPositionsInThread($targetThreadId);
        if (!$newCounters['firstPostId']) {
            XenForo_Db::rollback($db);
            return false;
        }
        // TODO: user message counts will go off if merging from a visible thread into a hidden one or vice versa
        $threadDw = XenForo_DataWriter::create('XenForo_DataWriter_Discussion_Thread');
        $threadDw->setExistingData($targetThreadId);
        $threadDw->rebuildDiscussionCounters($newCounters['visibleCount'] - 1, $newCounters['firstPostId'], $newCounters['lastPostId']);
        $threadDw->save();
        if ($options['redirect']) {
            $targetUrl = XenForo_Link::buildPublicLink('threads', $targetThread);
            $redirectKey = "thread-{$targetThread['thread_id']}-";
            foreach ($threads as $thread) {
                $redirectDw = XenForo_DataWriter::create('XenForo_DataWriter_Discussion_Thread');
                $redirectDw->setExistingData($thread, true);
                $redirectDw->set('discussion_type', 'redirect');
                $redirectDw->save();
                $this->getModelFromCache('XenForo_Model_ThreadRedirect')->insertThreadRedirect($thread['thread_id'], $targetUrl, $redirectKey, $options['redirectExpiry']);
            }
            $idsQuoted = $db->quote($mergeFromThreadIds);
            $db->delete('xf_thread_watch', "thread_id IN ({$idsQuoted})");
            $db->delete('xf_thread_user_post', "thread_id IN ({$idsQuoted})");
        } else {
            foreach ($threads as $thread) {
                $deleteDw = XenForo_DataWriter::create('XenForo_DataWriter_Discussion_Thread');
                $deleteDw->setExistingData($thread, true);
                $deleteDw->delete();
            }
        }
        $forumIds = array();
        foreach ($threads as $thread) {
            $forumIds[$thread['node_id']] = $thread['node_id'];
        }
        foreach ($forumIds as $forumId) {
            $forumDw = XenForo_DataWriter::create('XenForo_DataWriter_Forum', XenForo_DataWriter::ERROR_SILENT);
            $forumDw->setExistingData($forumId);
            $forumDw->rebuildCounters();
            $forumDw->save();
        }
        $this->replaceThreadUserPostCounters($targetThreadId, $newCounters['userPosts']);
        $indexer = new XenForo_Search_Indexer();
        $indexer->quickIndex('post', $movePostIds);
        XenForo_Db::commit($db);
        return $threadDw->getMergedData();
    }
Example #3
0
 /**
  * Moves the specified posts (in the given threads) to a new thread. The
  * new thread will be created in this function.
  *
  * @param array $posts
  * @param array $sourceThreads
  * @param array $newThread Information about the new thread; first/last/poster info filled in automatically
  *
  * @return array|false New thread ID or false
  */
 public function movePostsToNewThread(array $posts, array $sourceThreads, array $newThread)
 {
     if (!$posts) {
         return false;
     }
     $firstPostId = 0;
     $firstPostDate = PHP_INT_MAX;
     foreach ($posts as $postId => $post) {
         $sourceThreadIds[$post['thread_id']] = true;
         if ($post['post_date'] < $firstPostDate || $post['post_date'] == $firstPostDate && $post['post_id'] < $firstPostId) {
             $firstPostId = $postId;
             $firstPostDate = $post['post_date'];
         }
     }
     if (!isset($posts[$firstPostId])) {
         return false;
     }
     $firstPost = $posts[$firstPostId];
     $postIds = array_keys($posts);
     // TODO: consider user message count issues if moving from invisible to visible, etc
     unset($newThread['thread_id']);
     $newThread['first_post_id'] = $firstPostId;
     $newThread['post_date'] = $firstPost['post_date'];
     $newThread['user_id'] = $firstPost['user_id'];
     $newThread['username'] = $firstPost['username'];
     $newThread['discussion_state'] = $firstPost['message_state'];
     $db = $this->_getDb();
     XenForo_Db::beginTransaction($db);
     $threadDw = XenForo_DataWriter::create('XenForo_DataWriter_Discussion_Thread');
     $threadDw->setOption(XenForo_DataWriter_Discussion::OPTION_REQUIRE_INSERT_FIRST_MESSAGE, false);
     $threadDw->bulkSet($newThread);
     $threadDw->save();
     $newThread = $threadDw->getMergedData();
     $db->update('xf_post', array('thread_id' => $newThread['thread_id']), 'post_id IN (' . $db->quote($postIds) . ')');
     $firstPostDw = XenForo_DataWriter::create('XenForo_DataWriter_DiscussionMessage_Post', XenForo_DataWriter::ERROR_SILENT);
     $firstPostDw->setExistingData($firstPostId);
     $firstPostDw->set('message_state', 'visible');
     $firstPostDw->save();
     $newCounters = $this->recalculatePostPositionsInThread($newThread['thread_id']);
     $threadDw = XenForo_DataWriter::create('XenForo_DataWriter_Discussion_Thread');
     $threadDw->setExistingData($newThread, true);
     $threadDw->set('reply_count', $newCounters['visibleCount'] - 1);
     $threadDw->updateLastPost();
     $threadDw->save();
     $this->_getThreadModel()->replaceThreadUserPostCounters($newThread['thread_id'], $newCounters['userPosts']);
     $reindexPostIds = $postIds;
     foreach ($sourceThreads as $sourceThread) {
         $threadDw = XenForo_DataWriter::create('XenForo_DataWriter_Discussion_Thread');
         $threadDw->setExistingData($sourceThread, true);
         $newSourceCounters = $this->recalculatePostPositionsInThread($sourceThread['thread_id']);
         if (!$newSourceCounters['firstPostId']) {
             // all posts removed -> delete
             $threadDw->delete();
         } else {
             if ($newSourceCounters['firstPostId'] != $sourceThread['first_post_id']) {
                 $sourceFirstPost = $this->getPostById($newSourceCounters['firstPostId']);
                 $threadDw->set('first_post_id', $sourceFirstPost['post_id']);
                 $threadDw->set('post_date', $sourceFirstPost['post_date']);
                 $threadDw->set('user_id', $sourceFirstPost['user_id']);
                 $threadDw->set('username', $sourceFirstPost['username']);
                 // TODO: possible situation where new first post is moderated
                 $reindexPostIds[] = $sourceFirstPost['post_id'];
             }
             $threadDw->set('reply_count', $newSourceCounters['visibleCount'] - 1);
             if ($newSourceCounters['lastPostId'] != $sourceThread['last_post_id']) {
                 $threadDw->updateLastPost();
             }
             $threadDw->save();
             $this->_getThreadModel()->replaceThreadUserPostCounters($sourceThread['thread_id'], $newSourceCounters['userPosts']);
         }
     }
     $indexer = new XenForo_Search_Indexer();
     $indexer->quickIndex('post', $reindexPostIds);
     XenForo_Db::commit($db);
     return $newThread;
 }