Exemplo n.º 1
0
 public static function initiate($method, array $args)
 {
     if (!defined('PHP_VERSION_ID') || PHP_VERSION_ID < 50307) {
         throw new GFNCore_Exception('This add-on does not support PHP versions lesser than 5.3.7', true);
     }
     if ($method == 'install' && !empty($args[0])) {
         $job = 'upgrade';
     } else {
         $job = $method;
     }
     /** @var GFNCore_Installer_Abstract $obj */
     $obj = new static();
     $obj->setJob($job);
     if ($method == 'install') {
         $obj->setNewData($args[1]);
         $obj->setXml($args[2]);
     }
     if (in_array($job, array('upgrade', 'uninstall'))) {
         $obj->setExistingData($args[0]);
     }
     $class = 'GFNCore_Installer_Controller_' . ucfirst($job);
     XenForo_Db::beginTransaction();
     try {
         /** @var GFNCore_Installer_Controller_Abstract $controller */
         $controller = new $class($obj);
         $controller->execute();
     } catch (Exception $e) {
         XenForo_Db::rollback();
         throw $e;
     }
     XenForo_Db::commit();
     $style = new GFNCore_Installer_Handler_Style();
     $style->handle($obj->getData()->addon_id);
 }
Exemplo n.º 2
0
 /**
  * Executes the spam cleaner against the specified user
  *
  * @param array Spam user
  * @param array Usually the result of the choices made on the spam cleaner options form
  * @param array Will be populated with a log of actions performed
  * @param string If a problem occurs, this will be populated with an error phrase key
  *
  * @return boolean
  */
 public function cleanUp(array $user, array $actions, &$log = array(), &$errorKey = '')
 {
     $db = $this->_getDb();
     XenForo_Db::beginTransaction($db);
     $options = XenForo_Application::get('options');
     $log = array();
     if (!empty($actions['ban_user'])) {
         if (!$this->_banUser($user, $log, $errorKey)) {
             XenForo_Db::rollback($db);
             return false;
         }
         if ($user['user_state'] == 'moderated') {
             // they're banned now, so we can approve them so we don't have to manually deal with them
             $this->_getUserModel()->update($user, 'user_state', 'valid');
         }
         if ($options->stopForumSpam['submitRejections'] && $options->stopForumSpam['apiKey']) {
             $registrationIps = $this->getModelFromCache('XenForo_Model_User')->getRegistrationIps($user['user_id']);
             $spamCheckData = $user;
             $spamCheckData['ip'] = reset($registrationIps);
             $this->getModelFromCache('XenForo_Model_SpamPrevention')->submitSpamUserData($spamCheckData);
         }
     }
     foreach ($this->getSpamHandlers() as $contentType => $spamHandler) {
         if ($spamHandler->cleanUpConditionCheck($user, $actions)) {
             if (!$spamHandler->cleanUp($user, $log, $errorKey)) {
                 XenForo_Db::rollback($db);
                 return false;
             }
         }
     }
     if (!empty($actions['delete_messages'])) {
         /** @var $reportModel XenForo_Model_Report */
         $reportModel = $this->getModelFromCache('XenForo_Model_Report');
         $reports = $reportModel->getReportsByContentUserId($user['user_id']);
         $reportModel->updateReports($reports, 'resolved', true);
     }
     if (!empty($log)) {
         if (!empty($actions['email_user'])) {
             $this->_emailUser($user, $actions['email'], $log);
         }
         $visitor = XenForo_Visitor::getInstance();
         // log progress
         $db->insert('xf_spam_cleaner_log', array('user_id' => $user['user_id'], 'username' => $user['username'], 'applying_user_id' => $visitor['user_id'], 'applying_username' => $visitor['username'], 'application_date' => XenForo_Application::$time, 'data' => $log ? serialize($log) : ''));
         XenForo_Model_Log::logModeratorAction('user', $user, 'spam_clean');
     }
     XenForo_Db::commit($db);
     return true;
 }
 public function expireTempUserChange(array $change)
 {
     $userId = $change['user_id'];
     $actionType = $change['action_type'];
     $actionModifier = $change['action_modifier'];
     if ($actionType != 'custom_field') {
         return parent::expireTempUserChange($change);
     }
     /**
      *
      * @var XenForo_DataWriter_User $dw
      */
     $dw = XenForo_DataWriter::create('XenForo_DataWriter_User', XenForo_DataWriter::ERROR_SILENT);
     if (!$dw->setExistingData($userId)) {
         return false;
     }
     $db = $this->_getDb();
     XenForo_Db::beginTransaction($db);
     $res = $db->query("\r\n\t\t\tDELETE FROM xf_user_change_temp\r\n\t\t\tWHERE user_change_temp_id = ?\r\n\t\t", $change['user_change_temp_id']);
     if (!$res->rowCount()) {
         // already deleted
         XenForo_Db::rollback($db);
         return false;
     }
     switch ($actionType) {
         case 'custom_field':
             $customFields = @unserialize($dw->get('custom_fields'));
             $currentValue = isset($customFields[$actionModifier]) ? $customFields[$actionModifier] : '';
             // if the field was changed to the current value, revert it
             // to the most recent new value or the original value if none
             if ($currentValue === $change['new_value']) {
                 $lastChange = $db->fetchRow("\r\n\t\t\t\t\t\tSELECT *\r\n\t\t\t\t\t\tFROM xf_user_change_temp\r\n\t\t\t\t\t\tWHERE user_id = ?\r\n\t\t\t\t\t\t\tAND action_type = 'custom_field'\r\n\t\t\t\t\t\t\tAND action_modifier = ?\r\n\t\t\t\t\t\tORDER BY create_date DESC\r\n\t\t\t\t\t\tLIMIT 1\r\n\t\t\t\t\t", array($userId, $actionModifier));
                 $oldValue = $lastChange ? $lastChange['new_value'] : $change['old_value'];
                 $fieldValues[$actionModifier] = $oldValue;
                 $fieldsShown = array_keys($fieldValues);
                 $dw->setCustomFields($fieldValues, $fieldsShown);
                 if ($dw->isChanged('custom_fields')) {
                     $dw->save();
                 }
             }
     }
     XenForo_Db::commit($db);
     return true;
 }
Exemplo n.º 4
0
 /**
  * Rolls a database transaction back.
  */
 protected function _rollbackDbTransaction()
 {
     XenForo_Db::rollback($this->_db);
     return true;
 }
Exemplo n.º 5
0
 public function massImportSmilies(array $smilies, array $smilieCategories, &$errors = array())
 {
     $db = $this->_getDb();
     $categoryMap = array();
     // get existing smilie categories to avoid duplication - just in case
     $existingCategories = $this->_getExistingSmilieCategoryIdsByTitle();
     XenForo_Db::beginTransaction();
     foreach ($smilieCategories as $smilieCategoryId => $smilieCategory) {
         $import = false;
         foreach ($smilies as $smilie) {
             if ($smilie['smilie_category_id'] == $smilieCategoryId) {
                 // only import categories that contain imported smilies
                 $import = true;
                 break;
             }
         }
         if ($import) {
             if (isset($existingCategories[$smilieCategory['title']])) {
                 // an existing category has the title of the incoming category, so use it
                 $categoryMap[$smilieCategoryId] = $existingCategories[$smilieCategory['title']];
             } else {
                 $dw = XenForo_DataWriter::create('XenForo_DataWriter_SmilieCategory');
                 $dw->set('display_order', $smilieCategory['display_order']);
                 $dw->setExtraData(XenForo_DataWriter_SmilieCategory::DATA_TITLE, $smilieCategory['title']);
                 if ($dwErrors = $dw->getErrors()) {
                     foreach ($dwErrors as $field => $error) {
                         $errors[$field . '__' . $smilieCategoryId] = $error;
                     }
                     XenForo_Db::rollback();
                     return;
                 } else {
                     $dw->save();
                     $categoryMap[$smilieCategoryId] = $dw->get('smilie_category_id');
                 }
             }
         }
     }
     $dataWriters = array();
     foreach ($smilies as $smilieId => $smilie) {
         $dw = XenForo_DataWriter::create('XenForo_DataWriter_Smilie');
         $dw->set('title', $smilie['title']);
         $dw->set('smilie_text', $smilie['smilie_text']);
         $dw->set('image_url', $smilie['image_url']);
         $dw->set('display_order', $smilie['display_order']);
         $dw->set('display_in_editor', $smilie['display_in_editor']);
         $dw->set('sprite_mode', $smilie['sprite_mode']);
         $dw->set('sprite_params', $smilie['sprite_params']);
         if ($smilie['smilie_category_id']) {
             if ($smilie['smilie_category_id'] < 0) {
                 $smilie['smilie_category_id'] = $categoryMap[$smilie['smilie_category_id']];
             }
         }
         $dw->set('smilie_category_id', $smilie['smilie_category_id']);
         if ($dwErrors = $dw->getErrors()) {
             foreach ($dwErrors as $field => $error) {
                 $errors[$field . '__' . $smilieId] = $error;
             }
         } else {
             $dataWriters[] = $dw;
         }
     }
     if (empty($errors)) {
         foreach ($dataWriters as $dw) {
             $dw->save();
         }
         XenForo_Db::commit();
     } else {
         XenForo_Db::rollback();
     }
 }
Exemplo n.º 6
0
 public function actionApiUpdateScope()
 {
     $visitor = XenForo_Visitor::getInstance();
     /* @var $oauth2Model bdApi_Model_OAuth2 */
     $oauth2Model = $this->getModelFromCache('bdApi_Model_OAuth2');
     $client = $this->_bdApi_getClientOrError(false);
     $userScopes = $oauth2Model->getUserScopeModel()->getUserScopes($client['client_id'], $visitor['user_id']);
     if (empty($userScopes)) {
         return $this->responseNoPermission();
     }
     if ($this->isConfirmedPost()) {
         $isRevoke = $this->_input->filterSingle('revoke', XenForo_Input::STRING);
         $isRevoke = !empty($isRevoke);
         XenForo_Db::beginTransaction();
         try {
             $scopes = $this->_input->filterSingle('scopes', XenForo_Input::STRING, array('array' => true));
             if (empty($scopes)) {
                 // no scopes are selected, that equals revoking
                 $isRevoke = true;
             }
             $userScopesChanged = false;
             foreach ($userScopes as $userScope) {
                 if ($isRevoke or !in_array($userScope['scope'], $scopes, true)) {
                     // remove the accepted user scope
                     $oauth2Model->getUserScopeModel()->deleteUserScope($client['client_id'], $visitor['user_id'], $userScope['scope']);
                     $userScopesChanged = true;
                 }
             }
             if ($userScopesChanged) {
                 // invalidate all existing tokens
                 $oauth2Model->getAuthCodeModel()->deleteAuthCodes($client['client_id'], $visitor['user_id']);
                 $oauth2Model->getRefreshTokenModel()->deleteRefreshTokens($client['client_id'], $visitor['user_id']);
                 $oauth2Model->getTokenModel()->deleteTokens($client['client_id'], $visitor['user_id']);
             }
             if ($isRevoke) {
                 // unsubscribe for user and notification
                 $oauth2Model->getSubscriptionModel()->deleteSubscriptions($client['client_id'], bdApi_Model_Subscription::TYPE_USER, $visitor['user_id']);
                 $oauth2Model->getSubscriptionModel()->deleteSubscriptions($client['client_id'], bdApi_Model_Subscription::TYPE_NOTIFICATION, $visitor['user_id']);
             }
             XenForo_Db::commit();
         } catch (Exception $e) {
             XenForo_Db::rollback();
             throw $e;
         }
         return $this->responseRedirect(XenForo_ControllerResponse_Redirect::RESOURCE_UPDATED, XenForo_Link::buildPublicLink('account/api'));
     } else {
         $viewParams = array('client' => $client, 'userScopes' => $userScopes);
         return $this->_getWrapper('account', 'api', $this->responseView('bdApi_ViewPublic_Account_Api_UpdateScope', 'bdapi_account_api_update_scope', $viewParams));
     }
 }
Exemplo n.º 7
0
    /**
     * Inserts the data of a single feed entry
     *
     * @param array $entryData
     * @param array $feedData
     * @param array $feed
     *
     * @return integer|boolean Thread ID on success, false on failure
     */
    protected function _insertFeedEntry(array $entryData, array $feedData, array $feed)
    {
        $db = $this->_getDb();
        XenForo_Db::beginTransaction($db);
        $writer = XenForo_DataWriter::create('XenForo_DataWriter_Discussion_Thread', XenForo_DataWriter::ERROR_SILENT);
        $writer->setOption(XenForo_DataWriter_Discussion::OPTION_TRIM_TITLE, true);
        $writer->bulkSet(array('node_id' => $feed['node_id'], 'prefix_id' => $feed['prefix_id'], 'discussion_state' => $feed['discussion_visible'] ? 'visible' : 'moderated', 'discussion_open' => $feed['discussion_open'], 'sticky' => $feed['discussion_sticky'], 'title' => $entryData['title'], 'user_id' => $feed['user_id']));
        // TODO: The wholeWordTrim() used here may not be exactly ideal. Any better ideas?
        if ($feed['user_id']) {
            // post as the specified registered user
            $writer->set('username', $feed['username']);
        } else {
            if ($entryData['author']) {
                // post as guest, using the author name(s) from the entry
                $writer->set('username', XenForo_Helper_String::wholeWordTrim($entryData['author'], 25, 0, ''));
            } else {
                // post as guest, using the feed title
                $writer->set('username', XenForo_Helper_String::wholeWordTrim($feed['title'], 25, 0, ''));
            }
        }
        $postWriter = $writer->getFirstMessageDw();
        $postWriter->setOption(XenForo_DataWriter_DiscussionMessage::OPTION_IS_AUTOMATED, true);
        $postWriter->setOption(XenForo_DataWriter_DiscussionMessage::OPTION_VERIFY_GUEST_USERNAME, false);
        $postWriter->set('message', $entryData['message']);
        $writer->save();
        $threadId = $writer->get('thread_id');
        if ($threadId) {
            try {
                $db->query('
					INSERT INTO xf_feed_log
						(feed_id, unique_id, hash, thread_id)
					VALUES
						(?, ?, ?, ?)
				', array($feed['feed_id'], utf8_substr($entryData['id'], 0, 250), $entryData['hash'], $threadId));
            } catch (Zend_Db_Exception $e) {
                XenForo_Db::rollback($db);
                return false;
            }
        }
        XenForo_Db::commit($db);
        return $threadId;
    }
Exemplo n.º 8
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();
    }
Exemplo n.º 9
0
 public function massImportHooks(array $hooks, &$errors = array())
 {
     $db = $this->_getDb();
     XenForo_Db::beginTransaction();
     $dataWriters = array();
     foreach ($hooks as $hookId => $hook) {
         $dw = XenForo_DataWriter::create('Turki_Adv_DataWriter_Hooks');
         $dw->set('hook_title', $hook['hook_title']);
         $dw->set('template', $hook['template']);
         $dw->set('hook_name', $hook['hook_name']);
         $dw->set('active', $hook['active']);
         if ($dwErrors = $dw->getErrors()) {
             foreach ($dwErrors as $field => $error) {
                 $errors[$field . '__' . $hookId] = $error;
             }
         } else {
             $dataWriters[] = $dw;
         }
     }
     if (empty($errors)) {
         foreach ($dataWriters as $dw) {
             $dw->save();
         }
         XenForo_Db::commit();
     } else {
         XenForo_Db::rollback();
     }
 }
Exemplo n.º 10
0
 /**
  * Removes the specified user group change set.
  *
  * @param integer $userId
  * @param string $key Change set key
  *
  * @return boolean True on success
  */
 public function removeUserGroupChange($userId, $key)
 {
     $oldGroups = $this->getUserGroupChangesForUser($userId);
     if (!isset($oldGroups[$key])) {
         // already removed?
         return true;
     }
     $newGroups = $oldGroups;
     unset($newGroups[$key]);
     $db = $this->_getDb();
     XenForo_Db::beginTransaction($db);
     $success = $this->_applyUserGroupChanges($userId, $oldGroups, $newGroups);
     if ($success) {
         $db->delete('xf_user_group_change', 'user_id = ' . $db->quote($userId) . ' AND change_key = ' . $db->quote($key));
         XenForo_Db::commit($db);
     } else {
         XenForo_Db::rollback($db);
     }
     return $success;
 }
Exemplo n.º 11
0
 /**
  * Imports private messages etc. into a XenForo conversation
  *
  * @param integer Source ID
  * @param array $conversation Data for XenForo_DataWriter_ConversationMaster
  * @param array $recipients Recipient data
  * @param array $messages Data for XenForo_DataWriter_ConversationMessage
  *
  * @return integer Imported conversation ID
  */
 public function importConversation($oldId, array $conversation, array $recipients, array $messages)
 {
     if (!$messages || $conversation['title'] === '') {
         return false;
     }
     $hasRecipients = false;
     foreach ($recipients as $recipient) {
         if ($recipient['recipient_state'] == 'active') {
             $hasRecipients = true;
             break;
         }
     }
     if (!$hasRecipients) {
         return false;
     }
     $conversation['reply_count'] = count($messages) - 1;
     $conversation['recipient_count'] = count($recipients);
     $db = $this->_getDb();
     XenForo_Db::beginTransaction($db);
     $conversationId = $this->_importData($oldId, 'XenForo_DataWriter_ConversationMaster', 'conversation', 'conversation_id', $conversation);
     if ($conversationId) {
         $firstMessage = null;
         $lastMessage = null;
         foreach ($messages as $messageId => $message) {
             $message['conversation_id'] = $conversationId;
             $messageId = $this->_importData($messageId, 'XenForo_DataWriter_ConversationMessage', 'conversation_message', 'message_id', $message);
             if (!$messageId) {
                 continue;
             }
             $message['message_id'] = $messageId;
             if (!$firstMessage) {
                 $firstMessage = $message;
             }
             $lastMessage = $message;
         }
         if (!$firstMessage) {
             XenForo_Db::rollback($db);
             return false;
         }
         $conversationUpdate = array('first_message_id' => $firstMessage['message_id'], 'last_message_id' => $lastMessage['message_id'], 'last_message_date' => $lastMessage['message_date'], 'last_message_user_id' => $lastMessage['user_id'], 'last_message_username' => utf8_substr($lastMessage['username'], 0, 50));
         $conversation += $conversationUpdate;
         $db->update('xf_conversation_master', $conversationUpdate, 'conversation_id = ' . $db->quote($conversationId));
         foreach ($recipients as $userId => $info) {
             $db->insert('xf_conversation_recipient', array('conversation_id' => $conversationId, 'user_id' => $userId, 'recipient_state' => $info['recipient_state'], 'last_read_date' => $info['last_read_date']));
             if ($info['recipient_state'] == 'active') {
                 if (isset($info['is_unread'])) {
                     $isUnread = $info['is_unread'];
                 } else {
                     $isUnread = $info['last_read_date'] >= $lastMessage['message_date'] ? 0 : 1;
                 }
                 $recipientUser = array('conversation_id' => $conversationId, 'owner_user_id' => $userId, 'is_unread' => $isUnread, 'reply_count' => $conversation['reply_count'], 'last_message_date' => $conversation['last_message_date'], 'last_message_id' => $conversation['last_message_id'], 'last_message_user_id' => $conversation['last_message_user_id'], 'last_message_username' => $conversation['last_message_username']);
                 $db->insert('xf_conversation_user', $recipientUser);
             }
         }
     }
     XenForo_Db::commit($db);
     return $conversationId;
 }
Exemplo n.º 12
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, 'log' => true, 'starterAlert' => false, 'starterAlertReason' => ''), $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);
        $idsQuoted = $db->quote($mergeFromThreadIds);
        $db->update('xf_post', array('thread_id' => $targetThreadId), 'post_id IN (' . $db->quote($movePostIds) . ')');
        $db->query("\n\t\t\tUPDATE IGNORE xf_thread_watch SET\n\t\t\t\tthread_id = ?\n\t\t\tWHERE thread_id IN ({$idsQuoted})\n\t\t", array($targetThreadId));
        $db->query("\n\t\t\tUPDATE IGNORE xf_tag_content SET\n\t\t\t\tcontent_id = ?\n\t\t\tWHERE content_type = 'thread' AND content_id IN ({$idsQuoted})\n\t\t", array($targetThreadId));
        $db->query("\n\t\t\tUPDATE IGNORE xf_thread_reply_ban SET\n\t\t\t\tthread_id = ?\n\t\t\tWHERE thread_id IN ({$idsQuoted})\n\t\t", array($targetThreadId));
        $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
        // TODO: user message counts will also go off if merging from a thread in a counting forum into a non-counting forum, or vice versa
        $threadDw = XenForo_DataWriter::create('XenForo_DataWriter_Discussion_Thread');
        $threadDw->setExistingData($targetThreadId);
        $threadDw->rebuildDiscussionCounters($newCounters['visibleCount'] - 1, $newCounters['firstPostId'], $newCounters['lastPostId']);
        $viewCount = $threadDw->get('view_count');
        foreach ($threads as $thread) {
            $viewCount += $thread['view_count'];
        }
        $threadDw->set('view_count', $viewCount);
        if ($threadDw->get('discussion_type') == '') {
            foreach ($threads as $thread) {
                if ($thread['discussion_type'] == 'poll') {
                    $pollMoved = $db->update('xf_poll', array('content_id' => $targetThreadId), "content_type = 'thread' AND content_id = " . $db->quote($thread['thread_id']));
                    if ($pollMoved) {
                        $threadDw->set('discussion_type', 'poll');
                        break;
                    }
                }
            }
        }
        $threadDw->save();
        $targetThread = $threadDw->getMergedData();
        foreach ($threads as $thread) {
            if ($thread['discussion_state'] == 'visible' && $options['starterAlert']) {
                $this->sendModeratorActionAlert('merge', $thread, $options['starterAlertReason'], array('targetTitle' => $targetThread['title'], 'targetLink' => XenForo_Link::buildPublicLink('threads', $targetThread)));
            }
        }
        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']);
            }
            $db->delete('xf_thread_watch', "thread_id IN ({$idsQuoted})");
            $db->delete('xf_thread_reply_ban', "thread_id IN ({$idsQuoted})");
            $db->delete('xf_thread_user_post', "thread_id IN ({$idsQuoted})");
            $db->delete('xf_poll', "content_type = 'thread' AND content_id IN ({$idsQuoted})");
            $dataHandler = XenForo_Search_DataHandler_Abstract::create('XenForo_Search_DataHandler_Thread');
            $indexer = new XenForo_Search_Indexer();
            $dataHandler->deleteFromIndex($indexer, $threads);
        } 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']);
        /** @var XenForo_Model_Tag $tagModel */
        $tagModel = $this->getModelFromCache('XenForo_Model_Tag');
        $tagModel->rebuildTagCache('thread', $targetThread['thread_id']);
        $tagModel->recalculateTagUsageByContentTagged('thread', $targetThread['thread_id']);
        XenForo_Application::defer('SearchIndexPartial', array('contentType' => 'post', 'contentIds' => $movePostIds));
        if ($options['log']) {
            XenForo_Model_Log::logModeratorAction('thread', $targetThread, 'merge_target', array('ids' => implode(', ', array_keys($threads))));
        }
        XenForo_Db::commit($db);
        return $targetThread;
    }
Exemplo n.º 13
0
 public function expireTempUserChange(array $change)
 {
     $userId = $change['user_id'];
     $actionType = $change['action_type'];
     $actionModifier = $change['action_modifier'];
     /** @var XenForo_DataWriter_User $dw */
     $dw = XenForo_DataWriter::create('XenForo_DataWriter_User', XenForo_DataWriter::ERROR_SILENT);
     if (!$dw->setExistingData($userId)) {
         return false;
     }
     $db = $this->_getDb();
     XenForo_Db::beginTransaction($db);
     $res = $db->query("\n\t\t\tDELETE FROM xf_user_change_temp\n\t\t\tWHERE user_change_temp_id = ?\n\t\t", $change['user_change_temp_id']);
     if (!$res->rowCount()) {
         // already deleted
         XenForo_Db::rollback($db);
         return false;
     }
     switch ($actionType) {
         case 'groups':
             $this->_getUserModel()->removeUserGroupChange($userId, $actionModifier);
             break;
         case 'field':
             // if the field was changed to the current value, revert it
             // to the most recent new value or the original value if none
             if (strval($dw->get($actionModifier)) === $change['new_value']) {
                 $lastChange = $db->fetchRow("\n\t\t\t\t\t\tSELECT *\n\t\t\t\t\t\tFROM xf_user_change_temp\n\t\t\t\t\t\tWHERE user_id = ?\n\t\t\t\t\t\t\tAND action_type = 'field'\n\t\t\t\t\t\t\tAND action_modifier = ?\n\t\t\t\t\t\tORDER BY create_date DESC\n\t\t\t\t\t\tLIMIT 1\n\t\t\t\t\t", array($userId, $actionModifier));
                 $oldValue = $lastChange ? $lastChange['new_value'] : $change['old_value'];
                 $dw->set($actionModifier, $oldValue);
                 if ($dw->isChanged($actionModifier)) {
                     $dw->save();
                 }
             }
     }
     XenForo_Db::commit($db);
     return true;
 }
Exemplo n.º 14
0
 /**
  * Creates a thread that redirects to the target URL.
  *
  * @param string $targetUrl Target URL. May be relative or absolute.
  * @param array $newThread Information about a thread. State must be visible or not specified
  * @param string $redirectKey A unique key for relating this redirect to something else.
  * 		For example, when redirecting to another thread, this is used to relate the redirect record
  * 		to the thread it points to. If that thread is moved, we may need to remove the redirect.
  * @param integer $expiryDate Timestamp for expiry. 0 means never expires
  *
  * @return false|integer If successful, the ID of the redirect's thread
  */
 public function createRedirectThread($targetUrl, array $newThread, $redirectKey = '', $expiryDate = 0)
 {
     unset($newThread['thread_id'], $newThread['tags']);
     if (empty($newThread['discussion_state'])) {
         $newThread['discussion_state'] = 'visible';
     } else {
         if ($newThread['discussion_state'] != 'visible') {
             return false;
         }
     }
     $newThread['discussion_type'] = 'redirect';
     $newThread['first_post_id'] = 0;
     // remove any potential preview
     XenForo_Db::beginTransaction();
     $threadDw = XenForo_DataWriter::create('XenForo_DataWriter_Discussion_Thread', XenForo_DataWriter::ERROR_SILENT);
     $threadDw->setOption(XenForo_DataWriter_Discussion::OPTION_REQUIRE_INSERT_FIRST_MESSAGE, false);
     $threadDw->bulkSet($newThread, array('ignoreInvalidFields' => true));
     if (!$threadDw->save()) {
         XenForo_Db::rollback();
         return false;
     }
     $newThreadId = $threadDw->get('thread_id');
     $this->insertThreadRedirect($newThreadId, $targetUrl, $redirectKey, $expiryDate);
     XenForo_Db::commit();
     return $newThreadId;
 }
Exemplo n.º 15
0
 private static function _uninstallSelf($apiUrl)
 {
     $configOptionId = self::_getConfigOptionId($apiUrl);
     $templateTitle = $configOptionId;
     $templateModKey = $configOptionId;
     try {
         XenForo_Db::beginTransaction();
         /** @var XenForo_Model_AdminTemplate $templateModel */
         $templateModel = XenForo_Model::create('XenForo_Model_AdminTemplate');
         $template = $templateModel->getAdminTemplateByTitle($templateTitle);
         if (!empty($template)) {
             /** @var XenForo_DataWriter_AdminTemplate $templateDw */
             $templateDw = XenForo_DataWriter::create('XenForo_DataWriter_AdminTemplate');
             $templateDw->setExistingData($template, true);
             $templateDw->delete();
         }
         /** @var XenForo_Model_AdminTemplateModification $templateModModel */
         $templateModModel = XenForo_Model::create('XenForo_Model_AdminTemplateModification');
         $templateMod = $templateModModel->getModificationByKey($templateModKey);
         if (!empty($templateMod)) {
             /** @var XenForo_DataWriter_AdminTemplateModification $templateModDw */
             $templateModDw = XenForo_DataWriter::create('XenForo_DataWriter_AdminTemplateModification');
             $templateModDw->setExistingData($templateMod, true);
             $templateModDw->delete();
         }
         /** @var XenForo_DataWriter_Option $optionDw */
         $optionDw = XenForo_DataWriter::create('XenForo_DataWriter_Option');
         $optionDw->setExistingData($configOptionId);
         $optionDw->delete();
         if (XenForo_Application::debugMode()) {
             XenForo_Helper_File::log(__CLASS__, sprintf('%s($apiUrl=%s): ok', __METHOD__, $apiUrl));
         }
         XenForo_Db::commit();
     } catch (XenForo_Exception $e) {
         if (XenForo_Application::debugMode()) {
             XenForo_Helper_File::log(__CLASS__, sprintf('%s($apiUrl=%s): %s', __METHOD__, $apiUrl, $e->__toString()));
         }
         XenForo_Db::rollback();
     }
 }
Exemplo n.º 16
0
 public function importMedia($oldId, $tempFile, $contentType = '', array $xengalleryMedia = array(), array $xfAttachment = array(), array $xfAttachmentData = array())
 {
     $db = $this->_getDb();
     XenForo_Db::beginTransaction($db);
     $attachmentId = 0;
     if ($xfAttachment) {
         /** @var $attachmentDw XenForo_DataWriter_Attachment */
         $attachmentDw = XenForo_DataWriter::create('XenForo_DataWriter_Attachment');
         $attachmentDw->setImportMode(true);
         $attachmentDw->bulkSet($xfAttachment);
         $attachmentDw->save();
         $attachmentId = $attachmentDw->get('attachment_id');
     }
     $newId = false;
     if ($xengalleryMedia) {
         /** @var $mediaDw XenGallery_DataWriter_Media */
         $mediaDw = XenForo_DataWriter::create('XenGallery_DataWriter_Media');
         $mediaDw->setImportMode(true);
         $mediaDw->set('imported', XenForo_Application::$time);
         if ($this->_retainKeys) {
             $mediaDw->set('media_id', $oldId);
         }
         $xengalleryMedia['attachment_id'] = $attachmentId;
         $mediaDw->bulkSet($xengalleryMedia);
         if ($mediaDw->save()) {
             $newId = $mediaDw->get('media_id');
             $this->_getImportModel()->logImportData('xengallery_media', $oldId, $newId);
         }
         $media = $mediaDw->getMergedData();
         if ($media['likes'] && $media['like_users'] && $contentType) {
             $this->_convertLikesToNewContentType($oldId, $newId, $contentType, 'xengallery_media');
         }
     }
     if ($xfAttachmentData) {
         $fileIsVideo = false;
         $db->update('xf_attachment', array('content_id' => $media['media_id']), 'attachment_id = ' . $db->quote($attachmentId));
         $options = XenForo_Application::getOptions();
         $upload = new XenForo_Upload($xfAttachmentData['filename'], $tempFile);
         if ($upload->isImage()) {
             $image = new XenGallery_Helper_Image($tempFile);
             $image->importMode = true;
             $dimensions = array('width' => $image->getWidth(), 'height' => $image->getHeight());
             $tempThumbFile = tempnam(XenForo_Helper_File::getTempDir(), 'xfmg');
             if ($tempThumbFile && $image) {
                 $resized = $image->resize($dimensions['thumbnail_width'] = $options->xengalleryThumbnailDimension['width'], $dimensions['thumbnail_height'] = $options->xengalleryThumbnailDimension['height'], 'crop');
                 if (!$resized) {
                     return false;
                 }
                 $image->saveToPath($tempThumbFile);
                 unset($image);
             } else {
                 return false;
             }
         } else {
             $dimensions = array();
             $fileIsVideo = true;
             $tempThumbFile = false;
             if ($options->get('xengalleryVideoTranscoding', 'thumbnail')) {
                 try {
                     $video = new XenGallery_Helper_Video($upload->getTempFile());
                     $tempThumbFile = $video->getKeyFrame();
                     list($width, $height) = $video->getVideoDimensions();
                     $dimensions['width'] = $width;
                     $dimensions['height'] = $height;
                 } catch (XenForo_Exception $e) {
                 }
             }
             if (!$tempThumbFile) {
                 $tempThumbFile = tempnam(XenForo_Helper_File::getTempDir(), 'xfmg');
                 if ($tempThumbFile) {
                     @copy($options->xengalleryDefaultNoThumb, $tempThumbFile);
                 }
             }
             $image = new XenGallery_Helper_Image($tempThumbFile);
             if ($image) {
                 $image->resize($dimensions['thumbnail_width'] = $options->xengalleryThumbnailDimension['width'], $dimensions['thumbnail_height'] = $options->xengalleryThumbnailDimension['height'], 'crop');
                 $image->saveToPath($tempThumbFile);
                 unset($image);
             }
         }
         $mediaModel = $this->getModelFromCache('XenGallery_Model_Media');
         try {
             $dataDw = XenForo_DataWriter::create('XenForo_DataWriter_AttachmentData');
             $filename = $upload->getFileName();
             if ($fileIsVideo) {
                 $filename = strtr($filename, strtolower(substr(strrchr($filename, '.'), 1)), 'mp4');
                 $dataDw->set('file_path', $mediaModel->getVideoFilePath());
             }
             $dataDw->set('filename', $filename);
             $dataDw->bulkSet($dimensions);
             $dataDw->bulkSet($xfAttachmentData);
             $dataDw->setExtraData(XenForo_DataWriter_AttachmentData::DATA_TEMP_FILE, $tempFile);
             if ($tempThumbFile) {
                 $dataDw->setExtraData(XenForo_DataWriter_AttachmentData::DATA_TEMP_THUMB_FILE, $tempThumbFile);
             }
             $dataDw->setExtraData(XenGallery_DataWriter_AttachmentData::DATA_XMG_FILE_IS_VIDEO, $fileIsVideo);
             $dataDw->setExtraData(XenGallery_DataWriter_AttachmentData::DATA_XMG_DATA, true);
             $dataDw->save();
             $attachmentData = $dataDw->getMergedData();
             $db->update('xf_attachment', array('data_id' => $attachmentData['data_id']), 'attachment_id = ' . $db->quote($attachmentId));
         } catch (Exception $e) {
             if ($tempThumbFile) {
                 @unlink($tempThumbFile);
             }
             throw $e;
         }
         if ($tempThumbFile) {
             @unlink($tempThumbFile);
         }
     }
     if ($newId) {
         XenForo_Db::commit($db);
     } else {
         XenForo_Db::rollback($db);
     }
     return $newId;
 }