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

/**
 * Abstract controller for public actions.
 *
 * @package XenForo_Mvc
 */
abstract class XenForo_ControllerPublic_Abstract extends XenForo_Controller
{
    
/**
     * Pre-dispatch behaviors for the whole set of public controllers.
     */
    
final protected function _preDispatchType($action)
    {
        
//$this->_executeTrophyUpdate();
        
$this->_executePromotionUpdate();

        
$this->_assertCorrectVersion($action);
        
$this->_assertIpNotBanned();
        
$this->_assertViewingPermissions($action);
        
$this->_assertNotBanned();
        
$this->_assertBoardActive($action);

        if (
$this->_isDiscouraged())
        {
            
$this->_discourage($action);
        }

        
$this->_updateDismissedNoticeSessionCache();
        
$this->_updateModeratorSessionCaches();
        
$this->_updateAdminSessionCaches();
    }

    protected function 
_executeTrophyUpdate($force false)
    {
        if (!
XenForo_Application::isRegistered('session')  || XenForo_Application::getSession()->get('trophyChecked'))
        {
            return;
        }

        
$visitor XenForo_Visitor::getInstance();
        if (!
$visitor['user_id'] || ($visitor['last_activity'] > XenForo_Application::$time 1800 && !$force))
        {
            
// guest or we've been active recently, so let the cron do it
            
return;
        }

        
XenForo_Application::getSession()->set('trophyChecked'true);

        
/** @var $trophyModel XenForo_Model_Trophy */
        
$trophyModel $this->getModelFromCache('XenForo_Model_Trophy');
        if (
$trophyModel->updateTrophiesForUser($visitor->toArray()))
        {
            
// awarded trophies, reload
            
XenForo_Visitor::setup($visitor['user_id'], XenForo_Visitor::getVisitorSetupOptions());
        }
    }

    protected function 
_executePromotionUpdate($force false)
    {
        if (!
XenForo_Application::isRegistered('session') || XenForo_Application::getSession()->get('promotionChecked'))
        {
            return;
        }

        
$visitor XenForo_Visitor::getInstance();
        if (!
$visitor['user_id'] || ($visitor['last_activity'] > XenForo_Application::$time 1800 && !$force))
        {
            
// guest or we've been active recently, so let the cron do it
            
return;
        }

        
XenForo_Application::getSession()->set('promotionChecked'true);

        
/** @var $promotionModel XenForo_Model_UserGroupPromotion */
        
$promotionModel $this->getModelFromCache('XenForo_Model_UserGroupPromotion');
        if (
$promotionModel->updatePromotionsForUser($visitor->toArray()))
        {
            
// awarded promotions, reload
            
XenForo_Visitor::setup($visitor['user_id'], XenForo_Visitor::getVisitorSetupOptions());
        }
    }


    
/**
     * Asserts that the installed version of the board matches the files.
     *
     * @param string $action
     */
    
protected function _assertCorrectVersion($action)
    {
        if (
XenForo_Application::debugMode())
        {
            return;
        }

        if (!
XenForo_Application::get('config')->checkVersion)
        {
            return;
        }

        if (
XenForo_Application::$versionId != XenForo_Application::get('options')->currentVersionId)
        {
            
$response $this->responseMessage(new XenForo_Phrase('board_currently_being_upgraded'));
            throw 
$this->responseException($response503);
        }
    }

    
/**
     * Asserts that the user's IP address is not banned.
     */
    
protected function _assertIpNotBanned()
    {
        if (
XenForo_Application::isRegistered('bannedIps'))
        {
            
$bannedIps XenForo_Application::get('bannedIps');
        }
        else
        {
            
$bannedIps XenForo_Model::create('XenForo_Model_Banning')->rebuildBannedIpCache();
        }
        
        
$result $this->_getRequestIpConstraintCached($bannedIps'isIpBanned');
        if (
$result)
        {
            throw 
$this->responseException($this->responseReroute('XenForo_ControllerPublic_Error''bannedIp'));
        }
    }

    
/**
     * Checks whether a IP constraint is matched. The value is cached in the session.
     * The IP data should be an array with 2 keys:
     *  - version: unique identifier of cache revision
     *  - data: array of IPs to check (grouped by first byte)
     *
     * If the version differs, the cache value is ignored.
     * 
     * @param array $ipData
     * @param string $sessionKey Key to write to/read from in the session
     *
     * @return bool True if matched, false otherwise
     */
    
protected function _getRequestIpConstraintCached(array $ipData$sessionKey)
    {
        if (!
$ipData || empty($ipData['data']))
        {
            return 
false;
        }

        
$result null;
        
        if (
XenForo_Application::isRegistered('session'))
        {
            
$session XenForo_Application::getSession();
            if (
$session->isRegistered($sessionKey))
            {
                
$sessionValue $session->get($sessionKey);
                if (
$sessionValue 
                    
&& isset($sessionValue['version'])
                    && isset(
$ipData['version'])
                    && 
$sessionValue['version'] == $ipData['version']
                )
                {
                    
$result $sessionValue['result'];
                }
            }
        }
        else
        {
            
$session null;
        }

        if (
$result === null)
        {
            
$result = (!empty($ipData['data']) && $this->ipMatch($this->_getClientIps(), $ipData['data']));

            if (
$session)
            {
                
$session->set($sessionKey, array(
                    
'result' => $result,
                    
'version' => isset($ipData['version']) ? $ipData['version'] : 1
                
));
            }
        }
        
        return 
$result;
    }

    
/**
     * Assert that the visitor has the necessary viewing permissions.
     *
     * @param string $action
     */
    
protected function _assertViewingPermissions($action)
    {
        if (!
XenForo_Visitor::getInstance()->hasPermission('general''view'))
        {
            throw 
$this->getNoPermissionResponseException();
        }
    }

    
/**
     * Assert that the visitor is not banned.
     */
    
protected function _assertNotBanned()
    {
        if (
XenForo_Visitor::getInstance()->get('is_banned'))
        {
            throw 
$this->responseException($this->responseReroute('XenForo_ControllerPublic_Error''banned'), 403);
        }
    }

    
/**
     * Checks that the board is currently active (and can be viewed by the visitor)
     * or throws an exception.
     *
     * @param string $action
     */
    
protected function _assertBoardActive($action)
    {
        
$options XenForo_Application::get('options');
        if (!
$options->boardActive && !XenForo_Visitor::getInstance()->get('is_admin'))
        {
            throw 
$this->responseException($this->responseMessage($options->boardInactiveMessage), 503);
        }
    }

    
/**
    * Discourage the current visitor from remaining on the board by making theirs a bad experience.
    *
    * @param string $action
    */
    
protected function _discourage($action)
    {
        if (
XenForo_Application::isRegistered('discourageChecked'))
        {
            return;
        }
        
XenForo_Application::set('discourageChecked'true);

        
$options XenForo_Application::get('options');

        
// random loading delay
        
if ($options->discourageDelay['max'])
        {
            
usleep(mt_rand($options->discourageDelay['min'], $options->discourageDelay['max']) * 1000000);
        }

        
// TODO: server busy message?

        // random page redirect
        
if ($options->discourageRedirectChance && mt_rand(0100) < $options->discourageRedirectChance)
        {
            
header('Location: ' . ($options->discourageRedirectUrl $options->discourageRedirectUrl $options->boardUrl));
            die();
        }

        
// random blank page
        
if ($options->discourageBlankChance && mt_rand(0100) < $options->discourageBlankChance)
        {
            die();
        }

        
// randomly disable search
        
if ($options->discourageSearchChance && mt_rand(0100) < $options->discourageSearchChance)
        {
            
$options->set('enableSearch'false);
        }

        
// randomly disable news feed
        
if ($options->discourageNewsFeedChance && mt_rand(0100) < $options->discourageNewsFeedChance)
        {
            
$options->set('enableNewsFeed'false);
        }

        
// increase flood check time
        
if ($options->discourageFloodMultiplier 1)
        {
            
$options->set('floodCheckLength'$options->floodCheckLength $options->discourageFloodMultiplier);
        }
    }

    
/**
     * Checks whether a user is being discouraged, either by user preference or IP match
     *
     * @return boolean
     */
    
protected function _isDiscouraged()
    {
        if (
XenForo_Visitor::getInstance()->get('is_discouraged'))
        {
            
$result true;
        }
        else
        {
            if (
XenForo_Application::isRegistered('discouragedIps'))
            {
                
$discouragedIps XenForo_Application::get('discouragedIps');
            }
            else
            {
                
$discouragedIps XenForo_Model::create('XenForo_Model_Banning')->rebuildDiscouragedIpCache();
            }

            
$result $this->_getRequestIpConstraintCached($discouragedIps'isIpDiscouraged');
        }

        return 
$result;
    }

    
/**
     * Fetch the list of dismissed notices into the session if it's not already there
     */
    
protected function _updateDismissedNoticeSessionCache()
    {
        if (!
XenForo_Application::get('options')->enableNotices)
        {
            return;
        }

        if (!
XenForo_Application::isRegistered('session'))
        {
            return;
        }

        if (!
$userId XenForo_Visitor::getUserId())
        {
            return;
        }

        
$session XenForo_Application::getSession();
        if (!
$session->isRegistered('dismissedNotices'))
        {
            try
            {
                
$notices $this->getModelFromCache('XenForo_Model_Notice')->getDismissedNoticeIdsForUser($userId);
            }
            catch (
Exception $e)
            {
                
$notices = array();
            }

            
$session->set('dismissedNotices'$notices);
        }
    }

    
/**
     * Updates the moderator session caches if necessary.
     */
    
protected function _updateModeratorSessionCaches()
    {
        if (!
XenForo_Application::isRegistered('session'))
        {
            return;
        }

        
$visitor XenForo_Visitor::getInstance();
        if (!
$visitor['is_moderator'])
        {
            return;
        }

        
$this->_updateModeratorSessionReportCounts();
        
$this->_updateModeratorSessionModerationCounts();
    }

    
/**
     * Updates the counts in the session for reported content.
     */
    
protected function _updateModeratorSessionReportCounts()
    {
        if (
XenForo_Application::isRegistered('reportCounts'))
        {
            
$reportCounts XenForo_Application::get('reportCounts');
        }
        else
        {
            
$reportCounts $this->getModelFromCache('XenForo_Model_Report')->rebuildReportCountCache();
        }

        
$session XenForo_Application::get('session');
        
$sessionReportCounts $session->get('reportCounts');

        if (!
is_array($sessionReportCounts) || $sessionReportCounts['lastBuildDate'] < $reportCounts['lastModifiedDate'])
        {
            if (!
$reportCounts['activeCount'])
            {
                
$sessionReportCounts = array(
                    
'total' => 0,
                    
'assigned' => 0
                
);
            }
            else
            {
                
$sessionReportCounts $this->getModelFromCache('XenForo_Model_Report')->getActiveReportsCountsForUser();
            }

            
$sessionReportCounts['lastBuildDate'] = XenForo_Application::$time;
            
$session->set('reportCounts'$sessionReportCounts);
        }
    }

    
/**
     * Updates the counts in the session for the moderation queue.
     */
    
protected function _updateModeratorSessionModerationCounts()
    {
        if (
XenForo_Application::isRegistered('moderationCounts'))
        {
            
$counts XenForo_Application::get('moderationCounts');
        }
        else
        {
            
$counts $this->getModelFromCache('XenForo_Model_ModerationQueue')->rebuildModerationQueueCountCache();
        }

        
$session XenForo_Application::get('session');
        
$sessionCounts $session->get('moderationCounts');

        if (!
is_array($sessionCounts) || $sessionCounts['lastBuildDate'] < $counts['lastModifiedDate'])
        {
            if (!
$counts['total'])
            {
                
$sessionCounts = array('total' => 0);
            }
            else
            {
                
$sessionCounts = array(
                    
'total' => $this->getModelFromCache('XenForo_Model_ModerationQueue')->getModerationQueueCountForUser()
                );
            }

            
$sessionCounts['lastBuildDate'] = XenForo_Application::$time;

            
$session->set('moderationCounts'$sessionCounts);
        }
    }

    
/**
     * Updates the admin session caches if necessary.
     */
    
protected function _updateAdminSessionCaches()
    {
        if (!
XenForo_Application::isRegistered('session'))
        {
            return;
        }

        
$visitor XenForo_Visitor::getInstance();
        if (!
$visitor['is_admin'])
        {
            return;
        }

        
$this->_updateAdminSessionModerationCounts();
    }

    
/**
     * Updates the counts in the session for the user queue.
     */
    
protected function _updateAdminSessionModerationCounts()
    {
        
$session XenForo_Application::getSession();

        if (
$session->isRegistered('canAdminUsers')) {
            
$canAdminUsers $session->get('canAdminUsers');
        } else {
            
$canAdminUsers XenForo_Visitor::getInstance()->hasAdminPermission('user');
            
$session->set('canAdminUsers'$canAdminUsers);
        }

        if (!
$canAdminUsers) {
            return;
        }

        if (
XenForo_Application::isRegistered('userModerationCounts'))
        {
            
$counts XenForo_Application::get('userModerationCounts');
        }
        else
        {
            
$counts $this->getModelFromCache('XenForo_Model_User')->rebuildUserModerationQueueCache();
        }

        
$sessionCounts $session->get('userModerationCounts');

        if (!
is_array($sessionCounts) || $sessionCounts['lastBuildDate'] < $counts['lastModifiedDate'])
        {
            
$sessionCounts = array(
                
'total' => $counts['total'],
                
'lastBuildDate' => XenForo_Application::$time
            
);

            
$session->set('userModerationCounts'$sessionCounts);
        }
    }

    
/**
     * Gets the response for a generic no permission page.
     *
     * @return XenForo_ControllerResponse_Error
     */
    
public function responseNoPermission()
    {
        return 
$this->responseReroute('XenForo_ControllerPublic_Error''noPermission');
    }

    
/**
     * Asserts that the visitor is not flooding with the specified action.
     * Throws a response exception if flooding occurs.
     *
     * @param string $action
     * @param integer|null $floodingLimit
     */
    
public function assertNotFlooding($action$floodingLimit null)
    {
        if (!
XenForo_Visitor::getInstance()->hasPermission('general''bypassFloodCheck'))
        {
            
$floodTimeRemaining XenForo_Model_FloodCheck::checkFlooding($action$floodingLimit);
            if (
$floodTimeRemaining)
            {
                throw 
$this->responseException(
                    
$this->responseFlooding($floodTimeRemaining)
                );
            }
        }
    }

    protected function 
_buildLink($type$data null, array $params = array())
    {
        return 
XenForo_Link::buildPublicLink($type$data$params);
    }

    
/**
     * Helper to assert that access to this action requires registration and logged-in-edness.
     * Throws an exception for visitors that do not meet these criteria.
     */
    
protected function _assertRegistrationRequired()
    {
        if (!
XenForo_Visitor::getUserId())
        {
            throw 
$this->responseException(
                
$this->responseReroute('XenForo_ControllerPublic_Error''registrationRequired')
            );
        }
    }

    
/**
     * Gets the user names that are ignored in a particular batch of content.
     *
     * @param array $records Array of content (or may be a single record)
     *
     * @return array [user id] => user name
     */
    
protected function _getIgnoredContentUserNames(array $records)
    {
        
$first reset($records);
        if (!
is_array($first))
        {
            
$records = array($records);
        }

        
$names = array();

        foreach (
$records AS $content)
        {
            if (!empty(
$content['isIgnored']) && !empty($content['user_id']) && !empty($content['username']))
            {
                
$names[$content['user_id']] = $content['username'];
            }
        }

        return 
$names;
    }

    
/**
     * Gets an array containing the isRegistrationOrLogin parameter
     *
     * @return array
     */
    
protected function _getRegistrationContainerParams()
    {
        return array(
'hideLoginBar' => true);
    }
}
Онлайн: 1
Реклама