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

/**
 * Helper to manage/check the criteria that are used in things
 * like trophies and user notices.
 *
 * @package XenForo_Criteria
 */
class XenForo_Helper_Criteria
{
    protected static 
$_userFieldPrefix '__userField_';
    protected static 
$_userFieldPrefixLength 12;

    
/**
     * Determines if the given user matches the criteria. The provided
     * user should be a full user record; if fields are missing, an error
     * will not be thrown, and the criteria check will fail.
     *
     * @param array|string $criteria List of criteria, format: [] with keys rule and data; may be serialized
     * @param boolean $matchOnEmpty If true and there's no criteria, true is returned; otherwise, false
     * @param array|null $user Full user record to check against; if null, user visitor
     *
     * @return boolean
     */
    
public static function userMatchesCriteria($criteria$matchOnEmpty false, array $user null)
    {
        if (!
$criteria self::unserializeCriteria($criteria))
        {
            return (boolean)
$matchOnEmpty;
        }

        if (!
$user)
        {
            
$user XenForo_Visitor::getInstance()->toArray();
        }

        if (!isset(
$user['customFields']))
        {
            
$user['customFields'] = !empty($user['custom_fields']) ? @unserialize($user['custom_fields']) : array();
        }
        if (!isset(
$user['externalAuth']))
        {
            
$user['externalAuth'] = !empty($user['external_auth']) ? @unserialize($user['external_auth']) : array();
        }

        foreach (
$criteria AS $criterion)
        {
            
$data $criterion['data'];

            
// custom user fields
            
if (strpos($criterion['rule'], self::$_userFieldPrefix) === 0)
            {
                
$userFieldId substr($criterion['rule'], self::$_userFieldPrefixLength);

                if (!isset(
$user['customFields'][$userFieldId]))
                {
                    return 
false;
                }

                
$userField $user['customFields'][$userFieldId];

                
// text fields - check that data exists within the text value
                
if (isset($data['text']))
                {
                    if (
stripos($userField$data['text']) === false)
                    {
                        return 
false;
                    }
                }
                
// choice fields - check that data is in the choice array
                
else if (isset($data['choices']))
                {
                    
// multi-choice
                    
if (is_array($userField))
                    {
                        if (!
array_intersect($userField$data['choices']))
                        {
                            return 
false;
                        }
                    }
                    
// single choice
                    
else
                    {
                        if (!
in_array($userField$data['choices']))
                        {
                            return 
false;
                        }
                    }
                }
            }
            
// regular user info
            
else
            {
                switch (
$criterion['rule'])
                {
                    
// username
                    
case 'username':
                        
$names preg_split('/s*,s*/'utf8_strtolower($data['names']), -1PREG_SPLIT_NO_EMPTY);
                        if (!
in_array(utf8_strtolower($user['username']), $names))
                        {
                            return 
false;
                        }
                    break;

                    
// username-search
                    
case 'username_search':
                        if (
self::_arrayStringSearch($data['needles'], $user['username']) === false)
                        {
                            return 
false;
                        }
                    break;

                    
// email-search
                    
case 'email_search':
                        if (
self::_arrayStringSearch($data['needles'], $user['email']) === false)
                        {
                            return 
false;
                        }
                    break;


                    
// days since registration
                    
case 'registered_days':
                        if (!isset(
$user['register_date']))
                        {
                            return 
false;
                        }
                        
$daysRegistered floor((XenForo_Application::$time $user['register_date']) / 86400);
                        if (
$daysRegistered $data['days'])
                        {
                            return 
false;
                        }
                    break;

                    
// total messages posted
                    
case 'messages_posted':
                        if (!isset(
$user['message_count']) || $user['message_count'] < $data['messages'])
                        {
                            return 
false;
                        }
                    break;

                    
// maximum messages posted
                    
case 'messages_maximum':
                        if (!isset(
$user['message_count']) || $user['message_count'] > $data['messages'])
                        {
                            return 
false;
                        }
                    break;

                    
// total likes received
                    
case 'like_count':
                        if (!isset(
$user['like_count']) || $user['like_count'] < $data['likes'])
                        {
                            return 
false;
                        }
                    break;

                    
// like:message ratio
                    
case 'like_ratio':
                        if (empty(
$user['message_count']) || empty($user['like_count']))
                        {
                            return 
false;
                        }
                        if (
$user['like_count'] / $user['message_count'] < $data['ratio'])
                        {
                            return 
false;
                        }
                    break;

                    
// total trophy points accumulated
                    
case 'trophy_points':
                        if (!isset(
$user['trophy_points']) || $user['trophy_points'] < $data['points'])
                        {
                            return 
false;
                        }
                    break;

                    
// days since last activity
                    
case 'inactive_days':
                        if (!isset(
$user['last_activity']) || empty($user['user_id']))
                        {
                            return 
false;
                        }
                        
$daysInactive floor((XenForo_Application::$time $user['last_activity']) / 86400);
                        if (
$daysInactive $data['days'])
                        {
                            return 
false;
                        }
                    break;

                    
// current browsing style ID
                    
case 'style':
                        if (!isset(
$user['style_id']))
                        {
                            return 
false;
                        }
                        
$styleId = (empty($user['style_id']) ? XenForo_Application::get('options')->defaultStyleId $user['style_id']);
                        if (
$styleId != $data['style_id'])
                        {
                            return 
false;
                        }
                    break;

                    
// current browsing language ID
                    
case 'language':
                        if (!isset(
$user['language_id']))
                        {
                            return 
false;
                        }
                        
$languageId = (empty($user['language_id']) ? XenForo_Application::get('options')->defaultLanguageId $user['language_id']);
                        if (
$languageId != $data['language_id'])
                        {
                            return 
false;
                        }
                    break;

                    
// gender of user
                    
case 'gender':
                        if (!isset(
$user['gender']) || $user['gender'] != $data['gender'])
                        {
                            return 
false;
                        }
                    break;

                    
// user is logged in
                    
case 'is_logged_in':
                        if (empty(
$user['user_id']))
                        {
                            return 
false;
                        }
                    break;

                    
// user is a guest
                    
case 'is_guest':
                        if (!empty(
$user['user_id']))
                        {
                            return 
false;
                        }
                    break;

                    
// user is a moderator
                    
case 'is_moderator':
                        if (empty(
$user['is_moderator']))
                        {
                            return 
false;
                        }
                    break;

                    
// user is an admin
                    
case 'is_admin':
                        if (empty(
$user['is_admin']))
                        {
                            return 
false;
                        }
                    break;

                    
// user is banned
                    
case 'is_banned':
                        if (empty(
$user['is_banned']))
                        {
                            return 
false;
                        }
                    break;

                    
// search referer
                    
case 'from_search':
                        if (empty(
$user['from_search']))
                        {
                            return 
false;
                        }
                    break;

                    
// associated with Facebook
                    
case 'facebook':
                        if (empty(
$user['externalAuth']['facebook']))
                        {
                            return 
false;
                        }
                    break;

                    
// associated with Twitter
                    
case 'twitter':
                        if (empty(
$user['externalAuth']['twitter']))
                        {
                            return 
false;
                        }
                    break;

                    
// associated with Google
                    
case 'google':
                        if (empty(
$user['externalAuth']['google']))
                        {
                            return 
false;
                        }
                    break;

                    
// has no avatar (and is not a guest)
                    
case 'no_avatar':
                        if (empty(
$user['user_id']) || !empty($user['avatar_date']) || !empty($user['gravatar']))
                        {
                            return 
false;
                        }
                    break;

                    
// user group membership
                    
case 'user_groups':
                    case 
'not_user_groups':
                        if (!isset(
$user['user_group_id'], $user['secondary_group_ids']))
                        {
                            return 
false;
                        }

                        
$userGroups = ($user['secondary_group_ids'] ? explode(','$user['secondary_group_ids']) : array());

                        
$matched false;
                        if (!empty(
$data['user_group_ids']))
                        {
                            foreach (
$data['user_group_ids'] AS $matchUgId)
                            {
                                if (
$user['user_group_id'] == $matchUgId || in_array($matchUgId$userGroups))
                                {
                                    
$matched true;
                                    break;
                                }
                            }
                        }

                        if (
$criterion['rule'] == 'user_groups' && !$matched)
                        {
                            
// failed to match at least 1 group
                            
return false;
                        }
                        else if (
$criterion['rule'] == 'not_user_groups' && $matched)
                        {
                            
// matched at least one group and shouldn't have
                            
return false;
                        }
                    break;

                    
// user state
                    
case 'user_state':
                        if (!isset(
$user['user_state']) || $user['user_state'] != $data['state'])
                        {
                            return 
false;
                        }
                    break;

                    
// date criteria

                    // birthday
                    
case 'birthday':
                        if (empty(
$user['user_id']) || !isset($user['dob_day'], $user['dob_month']))
                        {
                            return 
false;
                        }
                        
$today XenForo_Locale::date(
                            
XenForo_Application::$time'j.n'null,
                            (isset(
$user['timezone']) ? $user['timezone'] : null)
                        );

                        if (
"$user[dob_day].$user[dob_month]!== $today)
                        {
                            return 
false;
                        }
                    break;

                    
// before date / time
                    
case 'before':
                    {
                        
$datetime = new DateTime("$data[ymd] $data[hh]:$data[mm]",
                            new 
DateTimeZone(($data['user_tz'] ? $user['timezone'] : $data['timezone'])));

                        if (
XenForo_Application::$time >= $datetime->format('U'))
                        {
                            return 
false;
                        }
                    }
                    break;

                    
// after date / time
                    
case 'after':
                    {
                        
$datetime = new DateTime("$data[ymd] $data[hh]:$data[mm]",
                            new 
DateTimeZone(($data['user_tz'] ? $user['timezone'] : $data['timezone'])));

                        if (
XenForo_Application::$time $datetime->format('U'))
                        {
                            return 
false;
                        }
                    }
                    break;

                    
// unknown criteria, assume failed unless something from a code event takes it
                    
default:
                    {
                        
$eventReturnValue false;

                        
XenForo_CodeEvent::fire('criteria_user', array($criterion['rule'], $data$user, &$eventReturnValue));

                        if (
$eventReturnValue === false)
                        {
                            return 
false;
                        }
                    }
                }
            }
        }

        return 
true;
    }


    
/**
     * Determines if the given page matches the criteria. The provided page data takes the form of
     * $params and $containerData from XenForo_ViewRenderer_HtmlPublic::_getNoticesContainerParams().
     *
     * @param array|string $criteria List of criteria, format: [] with keys rule and data; may be serialized
     * @param boolean $matchOnEmpty If true and there's no criteria, true is returned; otherwise, false
     * @param array $params
     * @param array $containerData
     *
     * @return boolean
     */
    
public static function pageMatchesCriteria($criteria$matchOnEmpty false, array $params, array $containerData)
    {
        if (!
$criteria self::unserializeCriteria($criteria))
        {
            return (boolean)
$matchOnEmpty;
        }

        foreach (
$criteria AS $criterion)
        {
            
$data $criterion['data'];

            switch (
$criterion['rule'])
            {
                
// browsing within one of the specified nodes
                
case 'nodes':
                {
                    if (!isset(
$containerData['navigation']) || !is_array($containerData['navigation']))
                    {
                        return 
false;
                    }
                    if (empty(
$data['node_ids']))
                    {
                        return 
false// no node ids specified
                    
}

                    if (empty(
$data['node_only']))
                    {
                        foreach (
$containerData['navigation'] AS $i => $navItem)
                        {
                            if (isset(
$navItem['node_id']) && in_array($navItem['node_id'], $data['node_ids']))
                            {
                                break 
2// break out of case 'nodes'...
                            
}
                        }
                    }

                    if (isset(
$containerData['quickNavSelected']))
                    {
                        
$quickNavSelected $containerData['quickNavSelected'];
                    }
                    else
                    {
                        
$quickNavSelected false;
                        foreach (
$containerData['navigation'] AS $i => $navItem)
                        {
                            if (isset(
$navItem['node_id']))
                            {
                                
$quickNavSelected 'node-' $navItem['node_id'];
                            }
                        }
                    }

                    if (
$quickNavSelected && in_array(preg_replace('/^.+-(d+)$/''$1'$quickNavSelected), $data['node_ids']))
                    {
                        break 
1;
                    }

                    return 
false;
                }
                break;

                
// browsing within the specified controller (and action)
                
case 'controller':
                {
                    if (!isset(
$params['controllerName']) || strtolower($params['controllerName']) != strtolower($data['name']))
                    {
                        return 
false;
                    }
                    if (!empty(
$data['action']) && isset($params['controllerAction']))
                    {
                        if (
strtolower($params['controllerAction']) != strtolower($data['action']))
                        {
                            return 
false;
                        }
                    }
                }
                break;

                
// browsing within the specified view
                
case 'view':
                {
                    if (!isset(
$params['viewName']) || strtolower($params['viewName']) != strtolower($data['name']))
                    {
                        return 
false;
                    }
                }
                break;

                
// viewing the specified content template
                
case 'template':
                {
                    if (!isset(
$params['contentTemplate']) || strtolower($params['contentTemplate']) != strtolower($data['name']))
                    {
                        return 
false;
                    }
                }
                break;

                
// browsing within the specified tab
                
case 'tab':
                {
                    if (!isset(
$params['selectedTabId']) || strtolower($params['selectedTabId']) != strtolower($data['id']))
                    {
                        return 
false;
                    }
                }
                break;

                
// unknown criteria, assume failed unless something from a code event takes it
                
default:
                {
                    
$eventReturnValue false;

                    
XenForo_CodeEvent::fire('criteria_page', array($criterion['rule'], $data$params$containerData, &$eventReturnValue));

                    if (
$eventReturnValue === false)
                    {
                        return 
false;
                    }
                }
            }
        }

        return 
true;
    }

    
/**
     * Prepares a list of criteria for selection by a user via the UI.
     * This will change if a criteria is repeatable.
     *
     * @param array|string $criteria Criteria in format: [], with keys rule and data; may be serialized
     *
     * @return array Format: [rule] => rule data or true if none
     */
    
public static function prepareCriteriaForSelection($criteria)
    {
        
$criteria self::unserializeCriteria($criteria);

        
$output = array();
        foreach (
$criteria AS $criterion)
        {
            
$data = (!empty($criterion['data']) ? $criterion['data'] : true);
            
$output[$criterion['rule']] = $data;
        }

        return 
$output;
    }

    public static function 
unserializeCriteria($criteria)
    {
        if (!
is_array($criteria))
        {
            
$criteria = @unserialize($criteria);
            if (!
is_array($criteria))
            {
                return array();
            }
        }

        return 
$criteria;
    }

    
/**
     * Formats the criteria for a DW.
     * Expected input format: [] with children: [rule] => name, [data] => info
     *
     * @param array|string $criteria Criteria array or serialize string; see above for format.
     *
     * @return array criteria
     */
    
public static function prepareCriteriaForSave($criteria)
    {
        
$criteria self::unserializeCriteria($criteria);

        
$criteriaFiltered = array();
        foreach (
$criteria AS $criterion)
        {
            if (!empty(
$criterion['rule']))
            {
                if (empty(
$criterion['data']) || !is_array($criterion['data']))
                {
                    
$criterion['data'] = array();
                }

                
$criteriaFiltered[] = array(
                    
'rule' => $criterion['rule'],
                    
'data' => $criterion['data']
                );
            }
        }

        return 
$criteriaFiltered;
    }

    
/**
     * Gets the data that is needed to display a list of criteria options for user selection.
     *
     * Tied with the helper_criteria_user admin template, via $userCriteriaData.
     *
     * @return array
     */
    
public static function getDataForUserCriteriaSelection()
    {
        
$hours = array();
        for (
$i 0$i 24$i++)
        {
            
$hh str_pad($i2'0'STR_PAD_LEFT);
            
$hours[$hh] = $hh;
        }

        
$minutes = array();
        for (
$i 0$i 60$i += 5)
        {
            
$mm str_pad($i2'0'STR_PAD_LEFT);
            
$minutes[$mm] = $mm;
        }

        return array(
            
'userGroups' => XenForo_Model::create('XenForo_Model_UserGroup')->getAllUserGroups(),
            
'styles' => XenForo_Model::create('XenForo_Model_Style')->getAllStylesAsFlattenedTree(),
            
'languages' => XenForo_Model::create('XenForo_Model_Language')->getAllLanguagesAsFlattenedTree(),
            
'timezones' => XenForo_Helper_TimeZone::getTimeZones(),
            
'hours' => $hours,
            
'minutes' => $minutes,
            
'userFieldGroups' => self::getUserFields(),
        );
    }

    
/**
     * Gets the data that is needed to display a list of criteria options for user selection.
     *
     * Tied with the helper_criteria_page admin template, via $pageCriteriaData.
     *
     * @return array
     */
    
public static function getDataForPageCriteriaSelection()
    {
        return array(
            
'nodes' => XenForo_Model::create('XenForo_Model_Node')->getAllNodes()
        );
    }

    
/**
     * Performs a case-insensitive search within $haystack for any of the $needles found in the comma-separated $needleList
     *
     * Example:
     *     haystack = 'user@gmail.com'
     *     needleList = '@yahoo, @gmail, @hotmail'
     *
     * @param string $needleList
     * @param string $haystack
     *
     * @return string|boolean Matched needle on success, false on failure
     */
    
protected static function _arrayStringSearch($needleList$haystack)
    {
        
$haystack utf8_strtolower($haystack);

        foreach (
preg_split('/s*,s*/'utf8_strtolower($needleList), -1PREG_SPLIT_NO_EMPTY) AS $needle)
        {
            if (
strpos($haystack$needle) !== false)
            {
                return 
$needle;
            }
        }

        return 
false;
    }

    public static function 
getUserFields()
    {
        
/* @var $fieldModel XenForo_Model_UserField */
        
$fieldModel XenForo_Model::create('XenForo_Model_UserField');

        
$userFieldGroups $fieldModel->getUserFieldGroups();

        
$userFields $fieldModel->prepareUserFields($fieldModel->getUserFields());

        foreach (
$userFields AS $userFieldId => $userField)
        {
            
$userField['fieldName'] = self::$_userFieldPrefix $userFieldId;
            
$userField['choices'] = $fieldModel->getUserFieldChoices($userFieldId$userField['field_choices'], true);
            
$userField['choiceCount'] = count($userField['choices']);

            
$userFieldGroups[$userField['display_group']]['userFields'][$userFieldId] = $userField;
        }

        return 
$userFieldGroups;
    }
}
Онлайн: 0
Реклама