Robust
Well-known member
Before: Timing: 0.0837 seconds - Memory: 8.908 MB - DB Queries: 10
After: Timing: 0.0904 seconds - Memory: 8.934 MB - DB Queries: 20
I get timing isn't created significantly, but with more add-ons it was doubled (from 0.1 to 0.2) and probably critical for bigger forums.
See https://www.apantic.com/community/threads/answered.1/?_debug=1
These are the classes that make DB queries:
	
	
	
		
	
	
	
		
	
	
		
			
	
				
			After: Timing: 0.0904 seconds - Memory: 8.934 MB - DB Queries: 20
I get timing isn't created significantly, but with more add-ons it was doubled (from 0.1 to 0.2) and probably critical for bigger forums.
See https://www.apantic.com/community/threads/answered.1/?_debug=1
These are the classes that make DB queries:
		PHP:
	
	<?php
class BestAnswer_Model_Vote extends XenForo_Model
{
    /**
     * Gets a best answer content record for a user that has voted on a piece of content.
     *
     * @param integer $postId
     * @param integer $userId
     *
     * @return array|false
     */
    public function getCurrentBestAnswerStatusOnPost($postId, $userId)
    {
        return $this->_getDb()->fetchRow('
            SELECT *
            FROM ba_votes
            WHERE post_id = ?
                AND vote_user_id = ?
        ', array($postId, $userId));
    }
    /**
     * Vote a post as best answer
     *
     * @param $postId int
     * @param $postUserId int
     * @param int|null $voteUserId
     * @param int|null $voteDate
     *
     * @return bool|false
     */
    public function votePost($postId, $postUserId, $voteUserId = null, $voteDate = null)
    {
        $visitor = XenForo_Visitor::getInstance();
        if($voteUserId === null)
        {
            $voteUserId = $visitor['user_id'];
        }
        if(!$voteUserId)
        {
            return false;
        }
        if($voteUserId != $visitor['user_id'])
        {
            /* @var $user XenForo_Model_User */
            $user = $this->getModelFromCache('XenForo_Model_User')->getUserById($voteUserId);
            if(!$user)
            {
                return false;
            }
            $voteUsername = $user['username'];
        }
        else
        {
            $voteUsername = $visitor['username'];
        }
        if($voteDate === null)
        {
            $voteDate = XenForo_Application::$time;
        }
        $post = $this->_getPostModel()->getPostById($postId);
        $threadId = $post['thread_id'];
        $db = $this->_getDb();
        XenForo_Db::beginTransaction($db);
        $query = $db->query('
            INSERT IGNORE INTO ba_votes
              (post_id, thread_id, vote_user_id, post_user_id, vote_date)
            VALUES
              (?, ?, ?, ?, ?)
        ', array($postId, $threadId, $voteUserId, $postUserId, $voteDate));
        if(!$query->rowCount())
        {
            XenForo_Db::commit($db);
            return false;
        }
        if($this->voteCountCheck($postId))
        {
            $this->recountVotesInThread($threadId);
        }
        $options = XenForo_Application::getOptions();
        if($options->baSetAnsweredPrefix)
        {
            $dwInput = array(
                'title' => new XenForo_Phrase($this->_getPrefixModel()->getPrefixTitlePhraseName($options->baSetAnsweredPrefix)),
                'prefix_id' => $options->baSetAnsweredPrefix
            );
            $forum = $this->_getForumModel()->getForumById($this->_getThreadModel()->getThreadById($threadId)['node_id']);
            if (!$this->_getPrefixModel()->verifyPrefixIsUsable($options->baSetAnsweredPrefix, $forum['node_id']))
            {
                $dwInput['prefix_id'] = 0;
            }
            $dw = XenForo_DataWriter::create('XenForo_DataWriter_Discussion_Thread');
            $dw->setExistingData($threadId);
            $dw->bulkSet($dwInput);
            $dw->setExtraData(XenForo_DataWriter_Discussion_Thread::DATA_FORUM, $forum);
            $dw->save();
        }
        if($postUserId)
        {
            /* @var $userModel XenForo_Model_User */
            $userModel = $this->getModelFromCache('XenForo_Model_User');
            $postUser = $userModel->getUserById($postUserId, array(
                'join' => XenForo_Model_User::FETCH_USER_OPTION | XenForo_Model_User::FETCH_USER_PROFILE
            ));
            if($postUser) {
                $db->query('
                    UPDATE `xf_user`
                    SET bestanswers = bestanswers + 1
                    WHERE user_id = ?
                ', $postUserId);
                if (!$userModel->isUserIgnored($postUser, $voteUserId)
                    && XenForo_Model_Alert::userReceivesAlert($postUser, 'post', 'vote'))
                {
                    $this->_getAlertModel()->alert(
                        $postUserId,
                        $voteUserId,
                        $voteUsername,
                        'post',
                        $postId,
                        'vote'
                    );
                }
            }
        }
        $this->_getNewsFeedModel()->publish(
            $voteUserId,
            $voteUsername,
            'post',
            $postId,
            'vote'
        );
        XenForo_Db::commit($db);
        return true;
    }
    public function unvotePost(array $vote)
    {
        $db = $this->_getDb();
        XenForo_Db::beginTransaction($db);
        $query = $db->query('
            DELETE FROM ba_votes
            WHERE vote_id = ?
        ', $vote['vote_id']);
        if(!$query->rowCount())
        {
            XenForo_Db::commit($db);
            return false;
        }
        $post = $this->_getPostModel()->getPostById($vote['post_id']);
        $threadId = $post['thread_id'];
        $this->recountVotesInThread($threadId);
        if($vote['post_user_id'])
        {
            $db->query('
                UPDATE `xf_user`
                SET bestanswers = bestanswers - 1
                WHERE user_id = ?
            ', $vote['post_user_id']);
            $this->_getAlertModel()->deleteAlerts(
                'post',
                $vote['post_id'],
                $vote['vote_user_id'],
                'vote'
            );
        }
        $this->_getNewsFeedModel()->delete(
            'post',
            $vote['post_id'],
            $vote['vote_user_id'],
            'vote'
        );
        XenForo_Db::commit($db);
        return true;
    }
    public function recountVotesInThread($threadId)
    {
        $db = $this->_getDb();
        $result = $db->fetchRow('
            SELECT COUNT(*) AS num_votes, ba_votes.post_id
            FROM ba_votes
              INNER JOIN xf_post
              ON ba_votes.post_id = xf_post.post_id
            WHERE ba_votes.thread_id = ?
            GROUP BY post_id
            ORDER BY num_votes desc
            LIMIT 1
        ', $threadId);
        $postId = $result['post_id'];
        if(empty($postId))
        {
            $postId = 0;
        }
        $db->query('
            UPDATE xf_thread
            SET bestanswer = ?
            WHERE thread_id = ?
        ', array($postId, $threadId));
    }
    public function voteCountCheck($postId)
    {
        $options = XenForo_Application::getOptions();
        if($options->baMinimumVotes)
        {
            $db = $this->_getDb();
            $result = $db->fetchRow('
            SELECT COUNT(*) AS num_votes, ba_votes.post_id
            FROM ba_votes
              INNER JOIN xf_post
              ON ba_votes.post_id = xf_post.post_id
            WHERE ba_votes.post_id = ?
            GROUP BY post_id
            ORDER BY num_votes desc
        ', $postId);
            $postId = $result['post_id'];
            if(empty($postId))
            {
                return new XenForo_Exception('Error getting vote count. Post ID is empty.');
            }
            return ($result['num_votes'] >= $options->baMinimumVotes) ? true : false;
        }
        return true;
    }
    public function canVotePost(array $post, array $thread, array $fourm, &$errorPhraseKey = '', array $nodePermissions = null, array $viewingUser = null)
    {
        $this->standardizeViewingUserReferenceForNode($thread['node_id'], $viewingUser, $nodePermissions);
        if (!$viewingUser['user_id'])
        {
            return false;
        }
        if ($post['message_state'] != 'visible')
        {
            return false;
        }
        if(!$this->votingEnabledInForum($thread['node_id']))
        {
            $errorPhraseKey = 'voting_not_enabled_in_forum';
            return false;
        }
        if ($post['user_id'] == $viewingUser['user_id'])
        {
            $errorPhraseKey = 'voting_own_content_not_allowed';
            return false;
        }
        if($post['post_id'] == $thread['first_post_id'])
        {
            $errorPhraseKey = 'cant_vote_first_post_in_thread';
            return false;
        }
        return XenForo_Permission::hasContentPermission($nodePermissions, 'vote');
    }
    public function votingEnabledInForum($forumId)
    {
        $options = XenForo_Application::getOptions();
        $enabledForums = $options->baEnabledForums;
        return (in_array($forumId, $enabledForums) ? true : false);
    }
    /**
     * @return XenForo_Model_Alert
     */
    protected function _getAlertModel()
    {
        return $this->getModelFromCache('XenForo_Model_Alert');
    }
    /**
     * @return XenForo_Model_NewsFeed
     */
    protected function _getNewsFeedModel()
    {
        return $this->getModelFromCache('XenForo_Model_NewsFeed');
    }
    /**
     * @return XenForo_Model_Post
     */
    protected function _getPostModel()
    {
        return $this->getModelFromCache('XenForo_Model_Post');
    }
    /**
     * @return XenForo_Model_ThreadPrefix
     */
    protected function _getPrefixModel()
    {
        return $this->getModelFromCache('XenForo_Model_ThreadPrefix');
    }
    /**
     * @return XenForo_Model_Thread
     */
    protected function _getThreadModel()
    {
        return $this->getModelFromCache('XenForo_Model_Thread');
    }
    /**
     * @return XenForo_Model_Forum
     */
    protected function _getForumModel()
    {
        return $this->getModelFromCache('XenForo_Model_Forum');
    }
}
	
		PHP:
	
	<?php
class BestAnswer_Helper_Time
{
    public static function getTimeByPostId($postId)
    {
        if($postId)
        {
            $db = XenForo_Application::getDb();
            $voteDate = $db->fetchOne('
                SELECT vote_date
                FROM ba_votes
                WHERE post_id = ?
            ', $postId);
            return $voteDate;
        }
        return false;
    }
}
	See https://www.apantic.com/community/threads/answered.1/?_debug=1
This is a copy without any other add-ons enabled.
Queries created by this add-on:
	
	
	
		
		This is a copy without any other add-ons enabled.
Queries created by this add-on:
- SELECT vote_date
FROM ba_votes
WHERE post_id = ?
Params: 2
Run Time: 0.000078
Select Type Table Type Possible Keys Key Key Len Ref Rows Extra
SIMPLE ba_votes ALL 1 Using where - SELECT *
FROM ba_votes
WHERE post_id = ?
AND vote_user_id = ?
Params: 1, 1
Run Time: 0.000191
Select Type Table Type Possible Keys Key Key Len Ref Rows Extra
SIMPLE ba_votes ALL 1 Using where - SELECT *
FROM ba_votes
WHERE post_id = ?
AND vote_user_id = ?
Params: 1, 1
Run Time: 0.000104
Select Type Table Type Possible Keys Key Key Len Ref Rows Extra
SIMPLE ba_votes ALL 1 Using where - SELECT *
FROM ba_votes
WHERE post_id = ?
AND vote_user_id = ?
Params: 2, 1
Run Time: 0.000113
Select Type Table Type Possible Keys Key Key Len Ref Rows Extra
SIMPLE ba_votes ALL 1 Using where - SELECT *
FROM ba_votes
WHERE post_id = ?
AND vote_user_id = ?
Params: 2, 1
Run Time: 0.000104
Select Type Table Type Possible Keys Key Key Len Ref Rows Extra
SIMPLE ba_votes ALL 1 Using where 
		Code:
	
	Included Files (97, XenForo Classes: 61)
index.php
library/XenForo/Autoloader.php
library/XenForo/Application.php
library/Zend/Registry.php
library/Lgpl/utf8.php
library/Zend/Config.php
library/config.php
library/XenForo/FrontController.php
library/XenForo/Dependencies/Public.php
library/XenForo/Dependencies/Abstract.php
library/Zend/Controller/Request/Http.php
library/Zend/Controller/Request/Abstract.php
library/Zend/Uri.php
library/Zend/Controller/Response/Http.php
library/Zend/Controller/Response/Abstract.php
library/XenForo/Model/DataRegistry.php
library/XenForo/Model.php
library/Zend/Cache.php
library/Zend/Cache/Backend/Memcached.php
library/Zend/Cache/Backend/ExtendedInterface.php
library/Zend/Cache/Backend/Interface.php
library/Zend/Cache/Backend.php
library/Zend/Cache/Core.php
library/XenForo/CodeEvent.php
library/XenForo/Options.php
library/XenForo/Link.php
library/XenForo/Template/Helper/Core.php
library/BestAnswer/Listener/Helper.php
library/XenForo/Router.php
library/XenForo/Route/Filter.php
library/XenForo/Route/Interface.php
library/XenForo/Route/ResponseSuffix.php
library/XenForo/Route/Prefix.php
library/XenForo/Route/Prefix/Threads.php
library/XenForo/RouteMatch.php
library/XenForo/ControllerPublic/Thread.php
library/XenForo/ControllerPublic/Abstract.php
library/XenForo/Controller.php
library/XenForo/Input.php
library/XenForo/Session.php
library/Zend/Db.php
library/Zend/Db/Adapter/Mysqli.php
library/Zend/Db/Adapter/Abstract.php
library/Zend/Db/Select.php
library/Zend/Db/Expr.php
library/Zend/Db/Profiler.php
library/Zend/Db/Statement/Mysqli.php
library/Zend/Db/Statement.php
library/Zend/Db/Statement/Interface.php
library/XenForo/Helper/Ip.php
library/XenForo/Visitor.php
library/XenForo/Model/User.php
library/Zend/Db/Profiler/Query.php
library/XenForo/Permission.php
library/XenForo/Phrase.php
library/XenForo/Locale.php
library/XenForo/ControllerHelper/ForumThreadPost.php
library/XenForo/ControllerHelper/Abstract.php
library/XenForo/Model/Thread.php
library/XenForo/Model/Forum.php
library/XenForo/Helper/String.php
library/XenForo/Model/Post.php
library/XenForo/Model/Attachment.php
library/XenForo/Model/Node.php
library/XenForo/Route/Prefix/Categories.php
library/XenForo/Route/Prefix/Forums.php
library/XenForo/ControllerResponse/View.php
library/XenForo/ControllerResponse/Abstract.php
library/XenForo/ViewRenderer/HtmlPublic.php
library/XenForo/ViewRenderer/Abstract.php
library/XenForo/Template/Public.php
library/XenForo/Template/Abstract.php
library/XenForo/ViewPublic/Thread/View.php
library/XenForo/ViewPublic/Base.php
library/XenForo/View.php
library/XenForo/BbCode/Parser.php
library/XenForo/BbCode/Formatter/Base.php
library/XenForo/ViewPublic/Helper/Message.php
library/XenForo/BbCode/TextWrapper.php
library/XenForo/ViewPublic/Helper/Editor.php
library/XenForo/Route/Prefix/Members.php
library/XenForo/Template/FileHandler.php
library/XenForo/Helper/File.php
internal_data/templates/S.1,L.1,thread_view.php
library/BestAnswer/Helper/PostUser.php
library/BestAnswer/Helper/Time.php
library/BestAnswer/Helper/PostMessage.php
library/Zend/Debug.php
library/XenForo/Route/Prefix/Posts.php
library/BestAnswer/Helper/CheckVote.php
library/BestAnswer/Model/Vote.php
library/XenForo/Model/Avatar.php
library/XenForo/Route/Prefix/SpamCleaner.php
internal_data/templates/S.1,L.1,editor.php
library/XenForo/ViewRenderer/Json.php
library/XenForo/Debug.php
internal_data/templates/S.1,L.1,PAGE_CONTAINER.php