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

/**
* Visitor Class
*
* @package XenForo_Core
*/
class XenForo_Visitor implements ArrayAccess
{
    
/**
    * Instance manager.
    *
    * @var XenForo_Visitor
    */
    
protected static $_instance;

    
/**
     * List of browser strings to check for in the {@link isBrowsingWith()} function.
     *
     * @var array
     */
    
protected static $_browsers = array(
        
'firefox' => 'Firefox',
        
'ie' => 'MSIE',
        
'webkit' => 'WebKit',
        
'opera' => 'Opera'
    
);

    protected static 
$_setupOptions null;

    
/**
    * Array of user info.
    *
    * @var array
    */
    
protected $_user = array();

    
/**
     * Language the user is using.
     *
     * @var array
     */
    
protected $_language = array();

    
/**
     * Cache of node-specific permissions for this user.
     *
     * @var array
     */
    
protected $_nodePermissions = array();

    
/**
     * List of admin permissions the user has. Note that this may not be populated
     * until necessary.
     *
     * @var array|null
     */
    
protected $_adminPermissions null;

    
/**
     * Stores if user is a super admin.
     *
     * @var boolean|null
     */
    
protected $_isSuperAdmin null;

    
/**
    * Protected constructor. Use {@link getInstance()} instead.
    */
    
protected function __construct()
    {
    }

    
/**
    * Gets the browsing user's info.
    *
    * @return XenForo_Visitor
    */
    
public static final function getInstance()
    {
        if (!
self::$_instance)
        {
            
self::setup(0); // setup sets the instance
        
}

        return 
self::$_instance;
    }

    public static final function 
setInstance(XenForo_Visitor $v)
    {
        
self::$_instance $v;
    }

    
/**
     * Determines if we have a visitor instance setup.
     *
     * @return boolean
     */
    
public static function hasInstance()
    {
        return (
self::$_instance true false);
    }

    
/**
     * Returns the user ID of the current visiting user
     *
     * @return integer User ID
     */
    
public static function getUserId()
    {
        
$object self::getInstance();

        return 
$object['user_id'];
    }

    public static function 
getVisitorSetupOptions()
    {
        return 
self::$_setupOptions;
    }

    
/**
     * Returns the permission combination ID of the current visiting user
     *
     * @return integer permission combination ID
     */
    
public static function getPermissionCombinationId()
    {
        
$object self::getInstance();

        return 
$object['permission_combination_id'];
    }

    
/**
     * Gets the user info in array format (for areas that require actual arrays).
     *
     * @return array
     */
    
public function toArray()
    {
        return 
$this->_user;
    }

    
/**
     * Gets the user's language.
     *
     * @return array
     */
    
public function getLanguage()
    {
        return 
$this->_language;
    }

    
/**
     * Determines if the visitor has a specific permission.
     *
     * @param string $group Permission group
     * @param string $permission
     *
     * @return boolean|int
     */
    
public function hasPermission($group$permission)
    {
        return 
XenForo_Permission::hasPermission($this->_user['permissions'], $group$permission);
    }

    
/**
     * Gets all global permissions for the visitor.
     *
     * @return array Format: [group][permission] => value
     */
    
public function getPermissions()
    {
        return 
$this->_user['permissions'];
    }

    
/**
     * Set the visitor's permissions for a particular node. Useful caching.
     *
     * @param integer $nodeId
     * @param array|string $permissions Permissions (may be serialized)
     */
    
public function setNodePermissions($nodeId$permissions)
    {
        if (
is_string($permissions))
        {
            
$permissions XenForo_Permission::unserializePermissions($permissions);
        }

        if (
is_array($permissions))
        {
            
$this->_nodePermissions[$nodeId] = $permissions;
        }
    }

    
/**
     * Returns true if there are node permissions cached for the specified node.
     *
     * @param integer $nodeId
     *
     * @return boolean
     */
    
public function hasNodePermissionsCached($nodeId)
    {
        return isset(
$this->_nodePermissions[$nodeId]);
    }

    
/**
     * Determines if the visitor has the specified permission on a specific node.
     *
     * @param integer $nodeId
     * @param string $permission
     *
     * @return boolean
     */
    
public function hasNodePermission($nodeId$permission)
    {
        return 
XenForo_Permission::hasContentPermission($this->getNodePermissions($nodeId), $permission);
    }

    
/**
     * Gets the visitor's permissions for a specific node. Permissions will be
     * fetched if necessary.
     *
     * @param integer $nodeId
     *
     * @return array
     */
    
public function getNodePermissions($nodeId)
    {
        if (!isset(
$this->_nodePermissions[$nodeId]))
        {
            
/* @var $permissionCacheModel XenForo_Model_PermissionCache */
            
$permissionCacheModel XenForo_Model::create('XenForo_Model_PermissionCache');

            
$this->_nodePermissions[$nodeId] = $permissionCacheModel->getContentPermissionsForItem(
                
$this->_user['permission_combination_id'], 'node'$nodeId
            
);
        }

        return 
$this->_nodePermissions[$nodeId];
    }

    
/**
     * Get all cached node permissions for the visitor. Not all nodes may be present.
     *
     * @return array Format: [node id] => permissions
     */
    
public function getAllNodePermissions()
    {
        return 
$this->_nodePermissions;
    }

    
/**
     * Determines if the current user has the specified admin permission.
     *
     * @param string $permissionId
     *
     * @return boolean
     */
    
public function hasAdminPermission($permissionId)
    {
        if (empty(
$this->_user['user_id']) || empty($this->_user['is_admin']))
        {
            return 
false;
        }

        if (
$this->isSuperAdmin())
        {
            return 
true;
        }

        if (!
is_array($this->_adminPermissions))
        {
            
$this->_adminPermissions XenForo_Model::create('XenForo_Model_Admin')->getAdminPermissionCacheForUser(
                
$this->_user['user_id']
            );
        }
        return !empty(
$this->_adminPermissions[$permissionId]);
    }

    
/**
     * Determines if current user is a super admin.
     *
     * @return boolean
     */
    
public function isSuperAdmin()
    {
        if (
$this->_isSuperAdmin === null)
        {
            
$superAdmins preg_split(
                
'#s*,s*#'XenForo_Application::get('config')->superAdmins,
                -
1PREG_SPLIT_NO_EMPTY
            
);
            
$this->_isSuperAdmin in_array($this->_user['user_id'], $superAdmins);
        }

        return 
$this->_isSuperAdmin;
    }

    
/**
     * Returns true if the visitor should be shown a CAPTCHA.
     *
     * @return boolean
     */
    
public function showCaptcha()
    {
        return (
$this->_user['user_id'] == 0); // TODO: permission
    
}

    
/**
     * Returns true if visitor can run searches. Does not cover find new or user content searches.
     *
     * @return boolean
     */
    
public function canSearch()
    {
        
// TODO: we should probably distinguish between search disabled and no permission to search
        
return ($this->hasPermission('general''search') && XenForo_Application::get('options')->enableSearch);
    }

    public function 
canFollow()
    {
        return (
$this->_user['user_id'] && $this->_user['user_state'] == 'valid');
    }

    
/**
     * Returns true if visitor can upload/change their avatar.
     *
     * @return boolean
     */
    
public function canUploadAvatar()
    {
        return (
            
$this->_user['user_id']
            && 
$this->hasPermission('avatar''allowed')
            && 
$this->hasPermission('avatar''maxFileSize') != 0
        
);
    }

    
/**
     * Returns true if the visitor can edit his/her signature.
     *
     * @return boolean
     */
    
public function canEditSignature()
    {
        return (
$this->_user['user_id']
            && 
$this->hasPermission('general''editSignature')
            && 
$this->hasPermission('signature''maxLines') != 0
        
);
    }

    
/**
     * @return bool
     */
    
public function canEditProfile()
    {
        return (
$this->_user['user_id'] && $this->hasPermission('general''editProfile'));
    }

    
/**
     * Determines if the visitor can update his/hew status.
     *
     * @return boolean
     */
    
public function canUpdateStatus()
    {
        if (!
$this->_user['user_id'])
        {
            return 
false;
        }

        return (
            
$this->_user['user_id']
            && 
$this->hasPermission('profilePost''view')
            && 
$this->hasPermission('profilePost''post')
        );
    }

    public function 
canStartConversations()
    {
        return 
XenForo_Model::create('XenForo_Model_User')->canStartConversations($null$this->_user);
    }

    
/**
     * Setup the visitor singleton.
     *
     * @param integer $userId User ID to setup as
     * @param array $options
     *
     * @return XenForo_Visitor
     */
    
public static function setup($userId, array $options = array())
    {
        
$userId intval($userId);

        
$options array_merge(array(
            
'languageId' => 0,
            
'permissionUserId' => 0
        
), $options);

        
/* @var $userModel XenForo_Model_User */
        
$userModel XenForo_Model::create('XenForo_Model_User');

        
$class XenForo_Application::resolveDynamicClass('XenForo_Visitor');
        
$object = new $class();
        if (
$userId && $user $userModel->getVisitingUserById($userId))
        {
            if (
$user['is_admin'] && $options['permissionUserId'])
            {
                
// force permissions for testing
                
$user $userModel->setPermissionsFromUserId($user$options['permissionUserId']);
            }

            
$object->_user $user;
        }
        else
        {
            
$object->_user $userModel->getVisitingGuestUser();

            if (
$options['languageId'])
            {
                
$object->_user['language_id'] = $options['languageId'];
            }
        }

        
$object->_user $userModel->prepareUser($object->_user);

        
$object->_user['referer'] = !empty($options['referer']) ? $options['referer'] : null;
        
$object->_user['from_search'] = !empty($options['fromSearch']);

        if (!empty(
$object->_user['ignored']))
        {
            
$ignored unserialize($object->_user['ignored']);
            
$object->_user['ignoredUsers'] = $ignored;
        }
        else
        {
            
$object->_user['ignoredUsers'] = array();
        }

        if (!
$object->_user['global_permission_cache'])
        {
            
// force a rebuild if we don't have the perm cache
            
$perms XenForo_Model::create('XenForo_Model_Permission')->rebuildPermissionCombinationById(
                
$object->_user['permission_combination_id']
            );
            
$object->_user['permissions'] = $perms $perms : array();
        }
        else
        {
            
$object->_user['permissions'] = XenForo_Permission::unserializePermissions($object->_user['global_permission_cache']);
        }

        
$object->setVisitorLanguage($object->_user['language_id']);
        
XenForo_Locale::setDefaultTimeZone($object->_user['timezone']);

        
self::$_instance $object;
        
self::$_setupOptions $options;

        
XenForo_CodeEvent::fire('visitor_setup', array(&self::$_instance));

        return 
self::$_instance;
    }

    public function 
setVisitorLanguage($languageId)
    {
        
$languages = (XenForo_Application::isRegistered('languages')
            ? 
XenForo_Application::get('languages')
            : 
XenForo_Model::create('XenForo_Model_Language')->getAllLanguagesForCache()
        );

        if (
$languageId && !empty($languages[$languageId]))
        {
            
$language $languages[$languageId];
        }
        else
        {
            
$defaultLanguageId XenForo_Application::get('options')->defaultLanguageId;
            if (!empty(
$languages[$defaultLanguageId]))
            {
                
$language $languages[$defaultLanguageId];
            }
            else
            {
                
$language reset($languages);
            }
        }

        if (!
$language)
        {
            return; 
// this probably shouldn't happen
        
}
        if (empty(
$language['phrase_cache']))
        {
            
$language['phrase_cache'] = array();
        }

        
$this->_language $language;

        
XenForo_Phrase::setLanguageId($language['language_id']);
        
XenForo_Phrase::setPhrases($language['phrase_cache']);

        
XenForo_Locale::setDefaultLanguage($language);
    }

    
/**
     * Checks to verify that the visitor is browsing with a particular user agent
     *
     * @param string $browser
     *
     * @return boolean
     */
    
public static function isBrowsingWith($browser)
    {
        if (!isset(
$_SERVER['HTTP_USER_AGENT']))
        {
            return 
false;
        }

        
$ua $_SERVER['HTTP_USER_AGENT'];

        if (
$browser == 'mobile')
        {
            if (
self::isBrowsingWith('webkit'))
            {
                if (
preg_match('# Mobile( Safari)?/#'$ua)) // iPhone, Android, etc
                
{
                    return 
true;
                }
                else if (
preg_match('#NokiaN[^/]*#'$ua))
                {
                    return 
true;
                }
                else if (
strpos('SymbianOS'$ua) !== false)
                {
                    return 
true;
                }
                else if (
strpos('Silk-Accelerated'$ua) !== false// Amazon Silk
                
{
                    return 
true;
                }
            }
            else if (
self::isBrowsingWith('opera') && preg_match('#Opera( |/)(Mini|8|9.[0-7])#'$ua))
            {
                
// well, this may not be mobile, but is very old :)
                
return true;
            }
            else if (
preg_match('#IEMobile/#'$ua))
            {
                return 
true;
            }
            else if (
preg_match('#^BlackBerry#'$ua))
            {
                return 
true;
            }

            return 
false;
        }

        
//TODO: Add version checking and more browsers
        
$browser strtolower($browser);
        if (
array_key_exists($browserself::$_browsers))
        {
            return (
strpos($uaself::$_browsers[$browser]) !== false);
        }
        else
        {
            return 
false;
        }
    }

    
/**
     * Returns whether or not the specified user is being followed by the visitor
     *
     * @param integer $userId
     *
     * @return boolean
     */
    
public function isFollowing($userId)
    {
        if (!
$this->_user['user_id'] || $userId == $this->_user['user_id'])
        {
            return 
false;
        }

        return 
XenForo_Model::create('XenForo_Model_User')->isFollowing($userId$this->_user);
    }

    
/**
     * Returns whether or not the specified user is being ignored by the visitor
     *
     * @param integer $userId
     *
     * @return boolean
     */
    
public function isIgnoring($userId)
    {
        if (!
$userId || !$this->_user['user_id'] || $userId == $this->_user['user_id'] || empty($this->_user['ignoredUsers']))
        {
            return 
false;
        }

        return isset(
$this->_user['ignoredUsers'][$userId]);
    }

    
/**
     * Determines if the visitor is a member of the specified user group
     *
     * @param integer $userGroupId
     * @param boolean $includeSecondaryGroups
     *
     * @return boolean
     */
    
public function isMemberOf($userGroupId$includeSecondaryGroups true)
    {
        static 
$userModel null;
        if (
$userModel === null)
        {
            
$userModel XenForo_Model::create('XenForo_Model_User');
        }

        return 
$userModel->isMemberOfUserGroup($this->_user$userGroupId$includeSecondaryGroups);
    }

    
/**
     * OO approach to getting a value from the visitor. Good if you want a single value in one line.
     *
     * @param string $name
     *
     * @return mixed False if the value can't be found
     */
    
public function get($name)
    {
        if (
array_key_exists($name$this->_user))
        {
            return 
$this->_user[$name];
        }
        else
        {
            return 
false;
        }
    }

    
/**
     * For ArrayAccess.
     *
     * @param string $offset
     */
    
public function offsetExists($offset)
    {
        return isset(
$this->_user[$offset]);
    }

    
/**
     * For ArrayAccess.
     *
     * @param string $offset
     */
    
public function offsetGet($offset)
    {
        return 
$this->_user[$offset];
    }

    
/**
     * For ArrayAccess.
     *
     * @param string $offset
     * @param mixed $value
     */
    
public function offsetSet($offset$value)
    {
        
$this->_user[$offset] = $value;
    }

    
/**
     * For ArrayAccess.
     *
     * @param string $offset
     */
    
public function offsetUnset($offset)
    {
        unset(
$this->_user[$offset]);
    }

    
/**
     * Magic method for array access
     */
    
public function __get($name)
    {
        return 
$this->get($name);
    }
}
Онлайн: 2
Реклама