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

/**
 * Model for moderators.
 *
 * @package XenForo_Moderator
 */
class XenForo_Model_Moderator extends XenForo_Model
{
    
/**
     * Gets a general moderator records based on user ID.
     *
     * @param integer $userId
     *
     * @return array|false
     */
    
public function getGeneralModeratorByUserId($userId)
    {
        return 
$this->_getDb()->fetchRow('
            SELECT moderator.*, user.username
            FROM xf_moderator AS moderator
            INNER JOIN xf_user AS user ON (user.user_id = moderator.user_id)
            WHERE moderator.user_id = ?
        '
$userId);
    }

    
/**
     * Gets all general moderators, potentially limited by super moderator status.
     *
     * @param boolean|null $isSuperModerator If not null, limits to super or non-super mods only
     *
     * @return array Format: [user id] => info
     */
    
public function getAllGeneralModerators($isSuperModerator null)
    {
        if (
$isSuperModerator === null)
        {
            
$moderatorClause '1=1';
        }
        else if (
$isSuperModerator)
        {
            
$moderatorClause 'moderator.is_super_moderator = 1';
        }
        else
        {
            
$moderatorClause 'moderator.is_super_moderator = 0';
        }

        return 
$this->fetchAllKeyed('
            SELECT moderator.*, user.username,
                user.avatar_date, user.gravatar
            FROM xf_moderator AS moderator
            INNER JOIN xf_user AS user ON (user.user_id = moderator.user_id)
            WHERE ' 
$moderatorClause '
            ORDER BY user.username
        '
'user_id');
    }

    
/**
     * Gets a matching content moderator.
     *
     * @param array $conditions
     * @param array $fetchOptions
     *
     * @return array|false
     */
    
public function getContentModerator(array $conditions, array $fetchOptions = array())
    {
        
$moderators $this->getContentModerators($conditions$fetchOptions);
        return 
reset($moderators);
    }

    
/**
     * Gets all matching content moderators.
     *
     * @param array $conditions
     * @param array $fetchOptions
     *
     * @return array Format: [moderator id] => info
     */
    
public function getContentModerators(array $conditions = array(), array $fetchOptions = array())
    {
        
$whereConditions $this->prepareContentModeratorConditions($conditions$fetchOptions);
        
$limitOptions $this->prepareLimitFetchOptions($fetchOptions);
        
$sqlClauses $this->prepareContentModeratorFetchOptions($fetchOptions);

        return 
$this->fetchAllKeyed($this->limitQueryResults(
            
'
                SELECT moderator_content.*, user.username
                    ' 
$sqlClauses['selectFields'] . '
                FROM xf_moderator_content AS moderator_content
                INNER JOIN xf_user AS user ON (user.user_id = moderator_content.user_id)
                ' 
$sqlClauses['joinTables'] . '
                WHERE ' 
$whereConditions '
                ' 
$sqlClauses['orderClause'] . '
            '
$limitOptions['limit'], $limitOptions['offset']
        ), 
'moderator_id');
    }

    
/**
     * Prepares the set of content moderator conditions.
     *
     * @param array $conditions
     * @param array $fetchOptions
     *
     * @return string SQL clause value for conditions
     */
    
public function prepareContentModeratorConditions(array $conditions, array &$fetchOptions)
    {
        
$sqlConditions = array();
        
$db $this->_getDb();

        if (isset(
$conditions['moderator_id']))
        {
            
$sqlConditions[] = 'moderator_content.moderator_id = ' $db->quote($conditions['moderator_id']);
        }

        if (!empty(
$conditions['content']))
        {
            if (
is_array($conditions['content']))
            {
                
$sqlConditions[] = 'moderator_content.content_type = ' $db->quote($conditions['content'][0]);
                
$sqlConditions[] = 'moderator_content.content_id = ' $db->quote($conditions['content'][1]);
            }
            else
            {
                
$sqlConditions[] = 'moderator_content.content_type = ' $db->quote($conditions['content']);
            }
        }

        if (isset(
$conditions['user_id']))
        {
            
$sqlConditions[] = 'moderator_content.user_id = ' $db->quote($conditions['user_id']);
        }

        return 
$this->getConditionsForClause($sqlConditions);
    }

    
/**
     * Prepares the content moderator fetch options into select fields, joins, and ordering.
     *
     * @param array $fetchOptions
     *
     * @return array Keys: selectFields, joinTables, orderClause
     */
    
public function prepareContentModeratorFetchOptions(array $fetchOptions)
    {
        
$selectFields '';
        
$joinTables '';
        
$orderBy '';

        if (isset(
$fetchOptions['order']))
        {
            switch (
$fetchOptions['order'])
            {
                case 
'username':
                    
$orderBy 'user.username';
                    break;
            }
        }
        else
        {
            
$orderBy 'user.username';
        }

        return array(
            
'selectFields' => $selectFields,
            
'joinTables' => $joinTables,
            
'orderClause' => ($orderBy "ORDER BY $orderBy'')
        );
    }

    
/**
     * Gets a content moderator by its unique ID.
     *
     * @param integer $id
     *
     * @return array|false
     */
    
public function getContentModeratorById($id)
    {
        return 
$this->getContentModerator(array('moderator_id' => $id));
    }

    
/**
     * Gets a content moderator by the unique combination of content and user ID.
     *
     * @param string $contentType
     * @param integer $contentId
     * @param integer $userId
     *
     * @return array|false
     */
    
public function getContentModeratorByContentAndUserId($contentType$contentId$userId)
    {
        return 
$this->getContentModerator(array(
            
'content' => array($contentType$contentId),
            
'user_id' => $userId
        
));
    }

    
/**
     * Gets all content moderator info for a specified user ID
     *
     * @param integer $userId
     *
     * @return array Format: [moderator id] => info
     */
    
public function getContentModeratorsByUserId($userId)
    {
        return 
$this->getContentModerators(
            array(
'user_id' => $userId),
            array(
'order' => false)
        );
    }

    
/**
     * Inserts or updates the necessary content moderator record.
     *
     * @param integer $userId
     * @param string $contentType
     * @param integer $contentId
     * @param array $modPerms List of moderator permissions to apply to this content
     * @param array $extra Extra info. Includes general_moderator_permissions and extra_user_group_ids
     *
     * @return integer Moderator ID
     */
    
public function insertOrUpdateContentModerator($userId$contentType$contentId, array $modPerms, array $extra = array())
    {
        
$contentModerator $this->getContentModeratorByContentAndUserId($contentType$contentId$userId);

        
$dw XenForo_DataWriter::create('XenForo_DataWriter_ModeratorContent');
        if (
$contentModerator)
        {
            
$dw->setExistingData($contentModeratortrue);
        }
        else
        {
            
$dw->set('content_type'$contentType);
            
$dw->set('content_id'$contentId);
            
$dw->set('user_id'$userId);
        }

        if (isset(
$extra['general_moderator_permissions']))
        {
            
$dw->setExtraData(XenForo_DataWriter_ModeratorContent::DATA_GENERAL_PERMISSIONS$extra['general_moderator_permissions']);
        }
        if (isset(
$extra['extra_user_group_ids']))
        {
            
$dw->setExtraData(XenForo_DataWriter_ModeratorContent::DATA_EXTRA_GROUP_IDS$extra['extra_user_group_ids']);
        }

        if (isset(
$extra['is_staff']))
        {
            
$dw->setOption(XenForo_DataWriter_ModeratorContent::OPTION_SET_IS_STAFF$extra['is_staff']);
        }

        
$dw->set('moderator_permissions'$modPerms);
        
$dw->save();

        return 
$dw->get('moderator_id');
    }

    
/**
     * Inserts or updates the necessary general moderator record.
     *
     * @param integer $userId
     * @param array $modPerms General moderator permissions. Does not include content-specific super mod perms.
     * @param boolean|null $isSuperModerator If non-null, the new super moderator setting
     * @param array $extra Extra data, including extra_user_group_ids and super_moderator_permissions
     *
     * @return integer Moderator ID
     */
    
public function insertOrUpdateGeneralModerator($userId, array $modPerms$isSuperModerator null, array $extra = array())
    {
        
$moderator $this->getGeneralModeratorByUserId($userId);

        
$dw XenForo_DataWriter::create('XenForo_DataWriter_Moderator');
        if (
$moderator)
        {
            
$dw->setExistingData($moderatortrue);
        }
        else
        {
            
$dw->set('user_id'$userId);
        }

        if (
$isSuperModerator !== null)
        {
            
$dw->set('is_super_moderator'$isSuperModerator);
        }

        if (isset(
$extra['extra_user_group_ids']))
        {
            
$dw->set('extra_user_group_ids'$extra['extra_user_group_ids']);
        }

        if (isset(
$extra['is_staff']))
        {
            
$dw->setOption(XenForo_DataWriter_Moderator::OPTION_SET_IS_STAFF$extra['is_staff']);
        }

        if (isset(
$extra['super_moderator_permissions']))
        {
            
$modPerms $this->mergeModeratorPermissions($modPerms$extra['super_moderator_permissions']);
        }

        
$dw->set('moderator_permissions'$modPerms);
        
$dw->save();

        return 
$userId;
    }

    
/**
     * Merges 2 sets of "grouped" moderator permissions.
     *
     * @param array $modPerms Existing permissions like [group][permission] => info
     * @param array $merge Merging permissions like [group][permission] => info
     *
     * @return array Merged set
     */
    
public function mergeModeratorPermissions(array $modPerms, array $merge)
    {
        foreach (
$merge AS $generalGroupId => $generalGroup)
        {
            foreach (
$generalGroup AS $generalId => $general)
            {
                
$modPerms[$generalGroupId][$generalId] = $general;
            }
        }

        return 
$modPerms;
    }

    
/**
     * Merges only general moderator permissions into a set of grouped permissions.
     * The initial set may contain more than general moderator permissions.
     *
     * @param array $modPerms Existing permissions like [group][permission] => info
     * @param array $merge Merging permissions like [group][permission] => info
     *
     * @return array Merged set
     */
    
public function mergeGeneralModeratorPermissions(array $modPerms, array $merge)
    {
        
$generalModeratorPermissions $this->getGeneralModeratorPermissions();

        foreach (
$merge AS $generalGroupId => $generalGroup)
        {
            foreach (
$generalGroup AS $generalId => $general)
            {
                if (isset(
$generalModeratorPermissions[$generalGroupId][$generalId]))
                {
                    
$modPerms[$generalGroupId][$generalId] = $general;
                }
            }
        }

        return 
$modPerms;
    }

    
/**
     * Merges a set of permission differences for setting/updating permission entries.
     *
     * @param array|string $newPermissions Set of new permissions (ie, new effective value). May be serialized.
     * @param array|string $existingPermissions Set of old permissions (ie, old effective value). May be serialized.
     * @param string $allowValue If a permission is to be allowed, the name of the allow state (allow or content_allow).
     *
     * @return array New effective permissions, with non-matching old values returned to "unset" state
     */
    
public function getModeratorPermissionsForUpdate($newPermissions$existingPermissions$allowValue 'allow')
    {
        
$finalPermissions = array();

        if (
is_string($newPermissions))
        {
            
$newPermissions unserialize($newPermissions);
        }
        else if (!
is_array($newPermissions))
        {
            
$newPermissions = array();
        }

        foreach (
$newPermissions AS $permissionGroupId => $permissionGroup)
        {
            foreach (
$permissionGroup AS $permissionId => $value)
            {
                
$finalPermissions[$permissionGroupId][$permissionId] = $allowValue;
            }
        }

        if (
is_string($existingPermissions))
        {
            
$existingPermissions unserialize($existingPermissions);
        }
        else if (!
is_array($existingPermissions))
        {
            
$existingPermissions = array();
        }

        foreach (
$existingPermissions AS $permissionGroupId => $permissionGroup)
        {
            foreach (
$permissionGroup AS $permissionId => $value)
            {
                if (!isset(
$finalPermissions[$permissionGroupId][$permissionId]))
                {
                    
$finalPermissions[$permissionGroupId][$permissionId] = 'unset';
                }
            }
        }

        return 
$finalPermissions;
    }

    
/**
     * Gets the permission interface group IDs that apply to all general moderators.
     *
     * @return array
     */
    
public function getGeneralModeratorInterfaceGroupIds()
    {
        return array(
'generalModeratorPermissions''profilePostModeratorPermissions''conversationModeratorPermissions');
    }

    
/**
     * Gets the permission interface group IDs that apply to the moderator in question.
     * If a content moderator, only includes general and that content's groups;
     * if a super moderator, includes all matching groups;
     * otherwise, includes only the general groups.
     *
     * @param array $moderator
     *
     * @return array List of interface group IDs
     */
    
public function getModeratorInterfaceGroupIds(array $moderator)
    {
        
$interfaceGroupIds $this->getGeneralModeratorInterfaceGroupIds();

        if (!empty(
$moderator['content_type']))
        {
            
$handler $this->getContentModeratorHandlers($moderator['content_type']);
            
$interfaceGroupIds array_merge($interfaceGroupIds$handler->getModeratorInterfaceGroupIds());
        }
        else if (!empty(
$moderator['is_super_moderator']))
        {
            foreach(
$this->getContentModeratorHandlers() AS $handler)
            {
                
$interfaceGroupIds array_merge($interfaceGroupIds$handler->getModeratorInterfaceGroupIds());
            }
        }

        return 
$interfaceGroupIds;
    }

    
/**
     * Gets all general moderator permissions.
     *
     * @return array Format: [group id][permission id] => permission info
     */
    
public function getGeneralModeratorPermissions()
    {
        return 
$this->getModeratorPermissions($this->getGeneralModeratorInterfaceGroupIds());
    }

    
/**
     * Gets moderator permissions from the specified interface groups.
     *
     * @param array $interfaceGroupIds
     *
     * @return array Format: [group id][permission id] => permission info
     */
    
public function getModeratorPermissions(array $interfaceGroupIds)
    {
        
$permissions $this->_getLocalCacheData('permissions');
        if (
$permissions === false)
        {
            
$permissions $this->_getPermissionModel()->getAllPermissions();
            
$this->setLocalCacheData('permissions'$permissions);
        }

        
$validPermissions = array();
        foreach (
$permissions AS $permission)
        {
            if (
$permission['permission_type'] != 'flag')
            {
                continue;
            }

            if (
in_array($permission['interface_group_id'], $interfaceGroupIds))
            {
                
$validPermissions[$permission['permission_group_id']][$permission['permission_id']] = $permission;
            }
        }

        return 
$validPermissions;
    }

    
/**
     * Gets the necessary moderator permissions and interface groups for the UI,
     *
     * @param array $interfaceGroupIds List of interface groups to pull permissions from
     * @param array $existingPermissions Existing permissions ([group id][permission id]), for selected values
     *
     * @return array List of interface groups, with "permissions" key (flat array)
     */
    
public function getModeratorPermissionsForInterface(array $interfaceGroupIds, array $existingPermissions = array())
    {
        
$permissionModel $this->_getPermissionModel();

        
$interfaceGroups $permissionModel->getAllPermissionInterfaceGroups();
        foreach (
$interfaceGroups AS $interfaceGroupId => &$interfaceGroup)
        {
            if (!
in_array($interfaceGroupId$interfaceGroupIds))
            {
                unset(
$interfaceGroups[$interfaceGroupId]);
            }
            else
            {
                
$interfaceGroup $permissionModel->preparePermissionInterfaceGroup($interfaceGroup);
            }
        }

        foreach (
$this->getModeratorPermissions($interfaceGroupIds) AS $groupId => $group)
        {
            foreach (
$group AS $permissionId => $permission)
            {
                if (isset(
$interfaceGroups[$permission['interface_group_id']]))
                {
                    
$permission $permissionModel->preparePermission($permission);
                    
$interfaceGroups[$permission['interface_group_id']]['permissions'][] = array(
                        
'label' => $permission['title'],
                        
'name'  => "[$permission[permission_group_id]][$permission[permission_id]]",
                        
'selected' => !empty($existingPermissions[$permission['permission_group_id']][$permission['permission_id']])
                    );
                }
            }
        }

        return 
$interfaceGroups;
    }

    
/**
     * Gets the list of possible extra user groups in "option" format.
     *
     * @param string|array $extraGroupIds List of existing extra group IDs; may be serialized.
     *
     * @return array List of user group options (keys: label, value, selected)
     */
    
public function getExtraUserGroupOptions($extraGroupIds)
    {
        return 
$this->getModelFromCache('XenForo_Model_UserGroup')->getUserGroupOptions(
            
$extraGroupIds
        
);
    }

    
/**
     * Gets all content moderator handler objects, or one for the specified content type.
     *
     * @param string|array|null $limitContentType If specified, gets handler for specified type(s) only
     *
     * @return XenForo_ModeratorHandler_Abstract|array|false
     */
    
public function getContentModeratorHandlers($limitContentType null)
    {
        
$contentTypes $this->_getLocalCacheData('moderatorHandlerPairs');
        if (
$contentTypes === false)
        {
            
$contentTypes $this->getContentTypesWithField('moderator_handler_class');
            
$this->setLocalCacheData('moderatorHandlerPairs'$contentTypes);
        }

        if (
is_string($limitContentType))
        {
            if (isset(
$contentTypes[$limitContentType]))
            {
                
$class $contentTypes[$limitContentType];
                if (!
class_exists($class))
                {
                    return 
false;
                }

                
$class XenForo_Application::resolveDynamicClass($class);
                return new 
$class();
            }
            else
            {
                return 
false;
            }
        }
        else if (
is_array($limitContentType))
        {
            
$handlers = array();
            foreach (
$contentTypes AS $contentType => $handlerClass)
            {
                if (
in_array($contentType$limitContentType))
                {
                    if (!
class_exists($handlerClass))
                    {
                        continue;
                    }

                    
$handlerClass XenForo_Application::resolveDynamicClass($handlerClass);
                    
$handlers[$contentType] = new $handlerClass();
                }
            }
        }
        else
        {
            
$handlers = array();
            foreach (
$contentTypes AS $contentType => $handlerClass)
            {
                if (!
class_exists($handlerClass))
                {
                    continue;
                }

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

        return 
$handlers;
    }

    
/**
     * Goes through a list of content moderators and fetches the content titles for all of them.
     * Items that are not returned by the handler will not have a "title" key.
     *
     * @param array $moderators
     *
     * @return array Moderators with "title" key where given
     */
    
public function addContentTitlesToModerators(array $moderators)
    {
        
$types = array();
        foreach (
$moderators AS $key => $moderator)
        {
            if (!
$moderator['content_type'])
            {
                continue;
            }

            
$types[$moderator['content_type']][$key] = $moderator['content_id'];
        }

        if (
$types)
        {
            
$handlers $this->getContentModeratorHandlers(array_keys($types));
            foreach (
$handlers AS $contentType => $handler)
            {
                
$titles $handler->getContentTitles($types[$contentType]);
                foreach (
$titles AS $key => $title)
                {
                    
$moderators[$key]['title'] = $title;
                }
            }
        }

        return 
$moderators;
    }

    
/**
     * Fetches an array containing $value for the value of each permission.
     * Useful for automatically populating super moderator records with a full permission set.
     *
     * @param mixed Value for every permission
     *
     * @return array $permissionSet[$groupId][$permId] = $value;
     */
    
public function getFullPermissionSet($value true)
    {
        
$permissionSet = array();

        foreach (
$this->getModeratorPermissions($this->getModeratorInterfaceGroupIds(array('is_super_moderator' => true))) AS $groupId => $group)
        {
            foreach (
$group AS $permId => $perm)
            {
                
$permissionSet[$groupId][$permId] = $value;
            }
        }

        return 
$permissionSet;
    }

    
/**
     * Returns the total number of members who are moderators
     * Note: distinct on user_id
     *
     * @return integer
     */
    
public function countModerators()
    {
        return 
$this->_getDb()->fetchOne('SELECT COUNT(*) FROM xf_moderator');
    }

    
/**
     * @return XenForo_Model_Permission
     */
    
protected function _getPermissionModel()
    {
        return 
$this->getModelFromCache('XenForo_Model_Permission');
    }
}
Онлайн: 1
Реклама