Вход Регистрация
Файл: library/XenForo/Model/Like.php
Строк: 574
<?php

/**
 * Model for liking content.
 *
 * @package XenForo_Like
 */
class XenForo_Model_Like extends XenForo_Model
{
    
/**
     * Gets a liked content record for a user that has liked a piece of content.
     *
     * @param string $contentType
     * @param integer $contentId
     * @param integer $userId
     *
     * @return array|false
     */
    
public function getContentLikeByLikeUser($contentType$contentId$userId)
    {
        return 
$this->_getDb()->fetchRow('
            SELECT *
            FROM xf_liked_content
            WHERE content_type = ?
                AND content_id = ?
                AND like_user_id = ?
        '
, array($contentType$contentId$userId));
    }

    
/**
     * Gets likes based on the content user.
     *
     * @param integer $userId
     * @param array $fetchOptions Fetch options. Supports limit only now.
     *
     * @return array Format: [like id] => info
     */
    
public function getLikesForContentUser($userId, array $fetchOptions = array())
    {
        
$limitOptions $this->prepareLimitFetchOptions($fetchOptions);

        return 
$this->fetchAllKeyed($this->limitQueryResults(
            
'
                SELECT liked_content.*,
                    user.*
                FROM xf_liked_content AS liked_content
                LEFT JOIN xf_user AS user ON (user.user_id = liked_content.like_user_id)
                WHERE liked_content.content_user_id = ?
                ORDER BY liked_content.like_date DESC
            '
$limitOptions['limit'], $limitOptions['offset']
        ), 
'like_id'$userId);
    }

    
/**
     * Count the number of likes a content user has received.
     *
     * @param integer $userId
     *
     * @return integer
     */
    
public function countLikesForContentUser($userId)
    {
        return 
$this->_getDb()->fetchOne('
            SELECT COUNT(*)
            FROM xf_liked_content
            WHERE content_user_id = ?
        '
$userId);
    }

    
/**
     * Get all the likes for a particular piece of content.
     *
     * @param string $contentType
     * @param integer $contentId
     * @param array $fetchOptions Fetch options (limit only right now)
     *
     * @return array Format: [like id] => info
     */
    
public function getContentLikes($contentType$contentId, array $fetchOptions = array())
    {
        
$limitOptions $this->prepareLimitFetchOptions($fetchOptions);

        return 
$this->fetchAllKeyed($this->limitQueryResults(
            
'
                SELECT liked_content.*,
                    user.*,
                    user_profile.*,
                    user_option.*
                FROM xf_liked_content AS liked_content
                INNER JOIN xf_user AS user ON
                    (user.user_id = liked_content.like_user_id)
                INNER JOIN xf_user_profile AS user_profile ON
                    (user_profile.user_id = user.user_id)
                INNER JOIN xf_user_option AS user_option ON
                    (user_option.user_id = user.user_id)
                WHERE liked_content.content_type = ?
                    AND liked_content.content_id = ?
                ORDER BY liked_content.like_date DESC
            '
$limitOptions['limit'], $limitOptions['offset']
        ), 
'like_id', array($contentType$contentId));
    }

    
/**
     * Gets the latest like users on a piece of content. Currently returns the last 5.
     *
     * @param string $contentType
     * @param integer $contentId
     *
     * @return array Format: [] => [user_id] and [username]
     */
    
public function getLatestContentLikeUsers($contentType$contentId)
    {
        
$likes $this->getContentLikes($contentType$contentId, array(
            
'limit' => 5
        
));

        
$output = array();
        foreach (
$likes AS $like)
        {
            
$output[] = array(
                
'user_id' => $like['like_user_id'],
                
'username' => $like['username']
            );
        }

        return 
$output;
    }

    
/**
     * Inserts a new like for a piece of content.
     *
     * @param string $contentType
     * @param integer $contentId
     * @param integer $contentUserId User that owns/created the content
     * @param integer|null $likeUserId User liking content; defaults to visitor
     * @param integer|null $likeDate Timestamp of liking; defaults to now.
     *
     * @return array|false List of latest like users or false
     */
    
public function likeContent($contentType$contentId$contentUserId$likeUserId null$likeDate null)
    {
        
$visitor XenForo_Visitor::getInstance();

        if (
$likeUserId === null)
        {
            
$likeUserId $visitor['user_id'];
        }
        if (!
$likeUserId)
        {
            return 
false;
        }

        if (
$likeUserId != $visitor['user_id'])
        {
            
$user $this->getModelFromCache('XenForo_Model_User')->getUserById($likeUserId);
            if (!
$user)
            {
                return 
false;
            }
            
$likeUsername $user['username'];
        }
        else
        {
            
$likeUsername $visitor['username'];
        }

        if (
$likeDate === null)
        {
            
$likeDate XenForo_Application::$time;
        }

        
$likeHandler $this->getLikeHandler($contentType);
        if (!
$likeHandler)
        {
            return 
false;
        }

        
$db $this->_getDb();
        
XenForo_Db::beginTransaction($db);

        
$result $db->query('
            INSERT IGNORE INTO xf_liked_content
                (content_type, content_id, content_user_id, like_user_id, like_date)
            VALUES
                (?, ?, ?, ?, ?)
        '
, array($contentType$contentId$contentUserId$likeUserId$likeDate));

        if (!
$result->rowCount())
        {
            
XenForo_Db::commit($db);
            return 
false;
        }

        if (
$contentUserId)
        {
            
$userModel $this->getModelFromCache('XenForo_Model_User');
            
$contentUser $this->getModelFromCache('XenForo_Model_User')->getUserById($contentUserId, array(
                
'join' => XenForo_Model_User::FETCH_USER_OPTION XenForo_Model_User::FETCH_USER_PROFILE
            
));

            if (
$contentUser)
            {
                
$db->query('
                    UPDATE xf_user
                    SET like_count = like_count + 1
                    WHERE user_id = ?
                '
$contentUserId);


                if (!
$userModel->isUserIgnored($contentUser$likeUserId)
                    && 
XenForo_Model_Alert::userReceivesAlert($contentUser$contentType'like')
                )
                {
                    
XenForo_Model_Alert::alert(
                        
$contentUserId,
                        
$likeUserId,
                        
$likeUsername,
                        
$contentType,
                        
$contentId,
                        
'like'
                    
);
                }
            }
        }

        
// publish to news feed
        
$this->getModelFromCache('XenForo_Model_NewsFeed')->publish(
            
$likeUserId,
            
$likeUsername,
            
$contentType,
            
$contentId,
            
'like'
        
);

        
$latestLikeUsers $this->getLatestContentLikeUsers($contentType$contentId);
        
$likeHandler->incrementLikeCounter($contentId$latestLikeUsers);

        
XenForo_Db::commit($db);

        return 
$latestLikeUsers;
    }

    
/**
     * Unlikes the specified like record.
     *
     * @param array $like
     *
     * @return array|false List of latest like users or false
     */
    
public function unlikeContent(array $like)
    {
        
$likeHandler $this->getLikeHandler($like['content_type']);
        if (!
$likeHandler)
        {
            return 
false;
        }

        
$db $this->_getDb();
        
XenForo_Db::beginTransaction($db);

        
$result $db->query('
            DELETE FROM xf_liked_content
            WHERE like_id = ?
        '
$like['like_id']);

        if (!
$result->rowCount())
        {
            
XenForo_Db::commit($db);
            return 
false;
        }

        if (
$like['content_user_id'])
        {
            
$db->query('
                UPDATE xf_user
                SET like_count = IF(like_count > 1, like_count - 1, 0)
                WHERE user_id = ?
            '
$like['content_user_id']);

            
$this->_getAlertModel()->deleteAlerts(
                
$like['content_type'], $like['content_id'], $like['like_user_id'], 'like'
            
);
        }

        
$this->_getNewsFeedModel()->delete(
            
$like['content_type'], $like['content_id'], $like['like_user_id'], 'like'
        
);

        
$latestLikeUsers $this->getLatestContentLikeUsers($like['content_type'], $like['content_id']);
        
$likeHandler->incrementLikeCounter($like['content_id'], $latestLikeUsers, -1);

        
XenForo_Db::commit($db);

        return 
$latestLikeUsers;
    }

    
/**
     * Deletes all the likes applied to a piece of content.
     *
     * @param string $contentType
     * @param integer|array $contentIds Single content ID or an array of them
     * @param boolean Update the likes counter for liked users
     */
    
public function deleteContentLikes($contentType$contentIds$updateUserLikeCounter true)
    {
        if (!
is_array($contentIds))
        {
            
$contentIds = array($contentIds);
        }
        if (!
$contentIds)
        {
            return;
        }

        
$db $this->_getDb();
        
$contentIdsQuoted $db->quote($contentIds);

        if (
$updateUserLikeCounter)
        {
            
$updates $db->fetchPairs('
                SELECT content_user_id, COUNT(*)
                FROM xf_liked_content
                WHERE content_type = ?
                    AND content_id IN (' 
$contentIdsQuoted ')
                GROUP BY content_user_id
            '
$contentType);

            foreach (
$updates AS $userId => $decrement)
            {
                
$decrementQuoted $db->quote($decrement);
                
$db->query("
                    UPDATE xf_user
                    SET like_count = IF(like_count > 
$decrementQuoted, like_count - $decrementQuoted, 0)
                    WHERE user_id = ?
                "
$userId);
            }
        }

        
$db->delete('xf_liked_content',
            
'content_type = ' $db->quote($contentType) . ' AND content_id IN (' $contentIdsQuoted ')'
        
);
    }

    
/**
     * Gets the like handler for a specific type of content.
     *
     * @param string $contentType
     *
     * @return false|XenForo_LikeHandler_Abstract
     */
    
public function getLikeHandler($contentType)
    {
        
$handlerClass $this->getContentTypeField($contentType'like_handler_class');
        if (!
$handlerClass || !class_exists($handlerClass))
        {
            return 
false;
        }

        
$handlerClass XenForo_Application::resolveDynamicClass($handlerClass);
        return new 
$handlerClass();
    }

    
/**
     * Gets the like handlers for all content types.
     *
     * @return array Array of XenForo_LikeHandler_Abstract objects
     */
    
public function getLikeHandlers()
    {
        
$handlerClasses $this->getContentTypesWithField('like_handler_class');
        
$handlers = array();
        foreach (
$handlerClasses AS $contentType => $handlerClass)
        {
            if (!
class_exists($handlerClass))
            {
                continue;
            }

            
$handlerClass XenForo_Application::resolveDynamicClass($handlerClass);
            
$handlers[$contentType] = new $handlerClass();
        }

        return 
$handlers;
    }

    
/**
     * Adds content specific data to a list of likes. Likes of unviewable content will
     * be removed.
     *
     * @param array $likes
     * @param array|null $viewingUser
     *
     * @return array Viewable likes with content key added (sub keys: url, title)
     */
    
public function addContentDataToLikes(array $likes, array $viewingUser null)
    {
        
$this->standardizeViewingUserReference($viewingUser);

        
$likesGrouped = array();
        foreach (
$likes AS $key => $like)
        {
            
$likesGrouped[$like['content_type']][$key] = $like['content_id'];
        }

        
$handlers $this->getLikeHandlers();
        foreach (
$likesGrouped AS $contentType => $contentIds)
        {
            if (!isset(
$handlers[$contentType]))
            {
                foreach (
$contentIds AS $key => $contentId)
                {
                    unset(
$likes[$key]);
                }
            }
            else
            {
                
$contents $handlers[$contentType]->getContentData($contentIds$viewingUser);
                
$listTemplateName $handlers[$contentType]->getListTemplateName();
                foreach (
$contentIds AS $key => $contentId)
                {
                    if (isset(
$contents[$contentId]))
                    {
                        
$likes[$key]['content'] = $contents[$contentId];
                        
$likes[$key]['listTemplateName'] = $listTemplateName;
                    }
                    else
                    {
                        unset(
$likes[$key]);
                    }
                }
            }
        }

        return 
$likes;
    }

    
/**
     * @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');
    }
}
Онлайн: 1
Реклама