<?php

/**
 * Model for threads.
 *
 * @package ModEss
 */
class ModEss_Model_Thread extends XFCP_ModEss_Model_Thread
{
	/**
	 * Gets permission-based conditions that apply to thread fetching functions.
	 *
	 * @param array $forum Forum the threads will belong to
	 * @param array|null $nodePermissions
	 * @param array|null $viewingUser
	 *
	 * @return array Keys: deleted (boolean), moderated (boolean or integer, if can only view single user's)
	 */
	public function getPermissionBasedThreadFetchConditions(array $forum, array $nodePermissions = null, array $viewingUser = null)
	{
		$conditions = parent::getPermissionBasedThreadFetchConditions($forum, $nodePermissions, $viewingUser);
		
		if (!$conditions['deleted'] && $this->_getModEssModel()->viewDeletedThreadPlaceholders($forum['node_id'], $nodePermissions, $viewingUser))
		{
			$conditions['deleted'] = true;
		}
		
		return $conditions;
	}
	
	/**
	 * Returns a thread record based
	 *
	 * @param integer $threadId
	 * @param array $fetchOptions Collection of options related to fetching
	 *
	 * @return array|false
	 */
	public function getThreadById($threadId, array $fetchOptions = array())
	{
		if (XenForo_Application::get('options')->modess_sticky_thread_order)
		{
			$fetchOptions['order'] = 'sticky_order';
			$fetchOptions['orderDirection'] = '';
		}
		
		return parent::getThreadById($threadId, $fetchOptions);
	}
	
	/**
	 * Gets all sticky threads in a particular forum.
	 *
	 * @param integer $forumId
	 * @param array $fetchOptions Collection of options that relate to fetching
	 *
	 * @return array Format: [thread id] => info
	 */
	public function getStickyThreadsInForum($forumId, array $conditions = array(), array $fetchOptions = array())
	{
		if (XenForo_Application::get('options')->modess_sticky_thread_order)
		{
			$fetchOptions['order'] = 'sticky_order';
			$fetchOptions['orderDirection'] = '';
		}
		
		return parent::getStickyThreadsInForum($forumId, $conditions, $fetchOptions);
	}
	
	/**
	 * Checks the 'join' key of the incoming array for the presence of the FETCH_x bitfields in this class
	 * and returns SQL snippets to join the specified tables if required
	 *
	 * @param array $fetchOptions containing a 'join' integer key build from this class's FETCH_x bitfields
	 *
	 * @return array Containing selectFields, joinTables, orderClause keys.
	 * 		Example: selectFields = ', user.*, foo.title'; joinTables = ' INNER JOIN foo ON (foo.id = other.id) '; orderClause = ORDER BY x.y
	 */
	public function prepareThreadFetchOptions(array $fetchOptions)
	{
		$stickyOrder = XenForo_Application::get('options')->modess_sticky_thread_order;
		
		if ($stickyOrder && !empty($fetchOptions['order']) && $fetchOptions['order'] == 'sticky_order')
		{
			$selectJoinOrder = parent::prepareThreadFetchOptions($fetchOptions);
			
			$selectJoinOrder['orderClause'] = 'ORDER BY sticky_display_order ASC, thread.last_post_date DESC';
			
			// order is 0 to 999, so if no order given use 1000 to force it to the bottom of the list
			$selectFields = ',
				IF(sticky_thread_order.display_order IS NULL, 1000, sticky_thread_order.display_order) AS sticky_display_order';
			$joinTables = '
				LEFT JOIN sticky_thread_order AS sticky_thread_order ON(sticky_thread_order.thread_id = thread.thread_id)';
	
			$selectJoinOrder['selectFields'] .= $selectFields;
			$selectJoinOrder['joinTables'] .= $joinTables;
			
			return $selectJoinOrder;
		}
		
		return parent::prepareThreadFetchOptions($fetchOptions);
	}

    public function prepareThreadBanConditions(array $conditions, array &$fetchOptions)
    {
        $sqlConditions = array();
        $db = $this->_getDb();

        $parent = parent::prepareThreadBanConditions($conditions, $fetchOptions);

        if (!empty($conditions['node_id']))
        {
            if (isset($fetchOptions['join']))
            {
                $fetchOptions['join'] |= self::FETCH_REPLY_BAN_FORUM;
            }
            else
            {
                $fetchOptions['join'] = self::FETCH_REPLY_BAN_FORUM;
            }

            $sqlConditions[] = 'node.node_id = ' . $db->quote($conditions['node_id']);
        }
        else
        {
            return $parent;
        }


        return '(' . $this->getConditionsForClause($sqlConditions) . ') and (' . $parent . ')';
    }

    public function addInlineModOptionToThread(array &$thread, array $forum, array $nodePermissions = null, array $viewingUser = null)
    {
        $parent = parent::addInlineModOptionToThread($thread, $forum, $nodePermissions, $viewingUser);
        if (XenForo_Visitor::getInstance()->hasPermission('general', 'modess_manageTags'))
        {
            $parent['modess_tag'] = true;
        }
        $thread['canInlineMod'] = (count($parent) > 0);
        return $parent;
    }

    public function modessGetThreadPosters($threadId)
    {
        return $this->fetchAllKeyed("select * from xf_thread_user_post where thread_id = ? order by post_count desc", 'user_id', array($threadId));
    }

    public function modessCanViewPosters(array $thread, array $forum, &$errorPhraseKey = '', array $nodePermissions = null, array $viewingUser = null)
    {
        $this->standardizeViewingUserReferenceForNode($thread['node_id'], $viewingUser, $nodePermissions);

        if (!XenForo_Permission::hasContentPermission($nodePermissions, 'modessCanViewContributors'))
        {
            return false;
        }

        return true;
    }

    public function modessCanViewModLogs(array $thread, array $forum, &$errorPhraseKey = '', array $nodePermissions = null, array $viewingUser = null)
    {
        $this->standardizeViewingUserReferenceForNode($thread['node_id'], $viewingUser, $nodePermissions);

        if (!XenForo_Permission::hasContentPermission($nodePermissions, 'modessThreadViewModLogs'))
        {
            return false;
        }

        return true;
    }
	
	/**
	 * @return ModEss_Model_ModEss
	 */
	protected function _getModEssModel()
	{
		return $this->getModelFromCache('ModEss_Model_ModEss');
	}
}