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

/**
* Input Filtering Class
*
* @package XenForo_Core
*/
class XenForo_Input
{
    const 
STRING     'string';
    const 
NUM        'num';
    const 
UNUM       'unum';
    const 
INT        'int';
    const 
UINT       'uint';
    const 
FLOAT      'float';
    const 
BOOLEAN    'boolean';
    const 
BINARY     'binary';
    const 
ARRAY_SIMPLE 'array_simple';
    const 
JSON_ARRAY 'json_array';
    const 
DATE_TIME       'dateTime';

    
/**
    * Default values for the input types
    *
    * @var array
    */
    
protected static $_DEFAULTS = array(
        
self::STRING    => '',
        
self::NUM       => 0,
        
self::UNUM      => 0,
        
self::INT       => 0,
        
self::UINT      => 0,
        
self::FLOAT     => 0.0,
        
self::BOOLEAN   => false,
        
self::BINARY    => '',
        
self::ARRAY_SIMPLE => array(),
        
self::JSON_ARRAY => array(),
        
self::DATE_TIME => 0
    
);

    
/**
     * Map of from-to pairs of things to manipulate in strings.
     *
     * @var array
     */
    
protected static $_strClean = array(
        
// strip a bunch of control characters
        
"x00" => ''// null
        
"x01" => ''// start of heading
        
"x02" => ''// start of text
        
"x03" => ''// end of text
        
"x04" => ''// end of transmission
        
"x05" => ''// enquiry
        
"x06" => ''// ack
        
"x07" => ''// bell
        
"x08" => ''// backspace
        
"x0B" => ''// vertical tab
        
"x0C" => ''// form feed
        
"x0D" => ''// carriage returns, because jQuery does so in .val()
        
"x0E" => ''// shift out
        
"x0F" => ''// shift in
        
"x10" => ''// data link escape
        
"x11" => ''// device ctrl 1
        
"x12" => ''// device ctrl 2
        
"x13" => ''// device ctrl 3
        
"x14" => ''// device ctrl 4
        
"x15" => ''// negative ack
        
"x16" => ''// sync idle
        
"x17" => ''// end of transmission block
        
"x18" => ''// cancel
        
"x19" => ''// end of medium
        
"x1A" => ''// substitute
        
"x1B" => ''// escape
        
"x1C" => ''// file sep
        
"x1D" => ''// group sep
        
"x1E" => ''// record sep
        
"x1F" => ''// unit sep

        
"xC2xA0" => ' '// nbsp
        
"xC2xAD" => ''// soft hyphen
        
"xE2x80x8B" => ''// zero width space
        
"xEFxBBxBF" => '' // zero width nbsp
    
);

    
/**
    * Cached cleaned variables. Key is the variable name as it was pulled
    *
    * @var array
    */
    
protected $_cleanedVariables = array();

    
/**
    * The request object that variables will be read from. May be null
    * if source data is populated instead
    *
    * @var Zend_Controller_Request_Http|null
    */
    
protected $_request null;

    
/**
     * Alternative to the request, data can come from an array.
     *
     * @var array|null
     */
    
protected $_sourceData null;

    
/**
    * Constructor
    *
    * @param Zend_Controller_Request_Http|array $source Source of input
    */
    
public function __construct($source)
    {
        if (
$source instanceof Zend_Controller_Request_Http)
        {
            
$this->_request $source;
        }
        else if (
is_array($source))
        {
            
$this->_sourceData $source;
        }
        else
        {
            throw new 
XenForo_Exception('Must pass an array or Zend_Controller_Request_Http object to XenForo_Input');
        }
    }

    
/**
    * Filter an individual item
    *
    * @param string $variableName Name of the input variable
    * @param mixed $filterData Filter information, can be a single constant or an array containing a filter and options
    * @param array $options Filtering options
    *
    * @return mixed Value after being cleaned
    */
    
public function filterSingle($variableName$filterData, array $options = array())
    {
        
$filters = array();

        if (
is_string($filterData))
        {
            
$filters = array($filterData);
        }
        else if (
is_array($filterData) && isset($filterData[0]))
        {
            
$filters is_array($filterData[0]) ? $filterData[0] : array($filterData[0]);

            if (isset(
$filterData[1]) && is_array($filterData[1]))
            {
                
$options array_merge($options$filterData[1]);
            }
            else
            {
                unset(
$filterData[0]);
                
$options array_merge($options$filterData);
            }
        }
        else
        {
            throw new 
XenForo_Exception("Invalid data passed to " __CLASS__ "::" __METHOD__);
        }

        
$firstFilter reset($filters);

        if (isset(
$options['default']))
        {
            
$defaultData $options['default'];
        }
        else if (
array_key_exists($firstFilterself::$_DEFAULTS))
        {
            
$defaultData self::$_DEFAULTS[$firstFilter];
        }
        else
        {
            
$defaultData null;
        }

        if (
$this->_request)
        {
            
$data $this->_request->getParam($variableName);
        }
        else
        {
            
$data = (isset($this->_sourceData[$variableName]) ? $this->_sourceData[$variableName] : null);
        }

        if (
$data === null)
        {
            
$data $defaultData;
        }

        foreach (
$filters AS $filterName)
        {
            if (isset(
$options['array']))
            {
                if (
is_array($data))
                {
                    foreach (
array_keys($data) AS $key)
                    {
                        
$data[$key] = self::_doClean($filterName$options$data[$key], $defaultData);
                    }
                }
                else
                {
                    
$data = array();
                    break;
                }
            }
            else
            {
                
$data self::_doClean($filterName$options$data$defaultData);
            }
        }

        
$this->_cleanedVariables[$variableName] = $data;
        return 
$data;
    }

    protected static function 
_doClean($filterName, array $filterOptions$data$defaultData)
    {
        switch (
$filterName)
        {
            case 
self::STRING:
                
$data is_scalar($data) ? strval($data) : $defaultData;
                if (
strlen($data) && !preg_match('/./u'$data))
                {
                    
$data $defaultData;
                }

                
$data self::cleanString($data);

                if (empty(
$filterOptions['noTrim']))
                {
                    
$data trim($data);
                }
            break;

            case 
self::NUM:
                
$data strval($data) + 0;
            break;

            case 
self::UNUM:
                
$data strval($data) + 0;
                
$data = ($data 0) ? $defaultData $data;
            break;

            case 
self::INT:
                
$data intval($data);
            break;

            case 
self::UINT:
                
$data = ($data intval($data)) < $defaultData $data;
            break;

            case 
self::FLOAT:
                
$data floatval($data);
            break;

            case 
self::BOOLEAN:
                if (
$data === 'n' || $data == 'no' || $data === 'N')
                {
                    
$data false;
                }
                else
                {
                    
$data = (boolean)$data;
                }
                break;

            case 
self::BINARY:
                
$data strval($data);
            break;

            case 
self::ARRAY_SIMPLE:
                if (!
is_array($data))
                {
                    
$data $defaultData;
                }
                
$data self::cleanStringArray($data);
            break;

            case 
self::JSON_ARRAY:
                if (
is_string($data))
                {
                    
$data json_decode($datatrue);
                }
                if (!
is_array($data))
                {
                    
$data $defaultData;
                }
                
$data self::cleanStringArray($data);
            break;

            case 
self::DATE_TIME:
                if (!
$data)
                {
                    
$data 0;
                }
                else if (
is_string($data))
                {
                    
$data trim($data);

                    if (
$data === strval(intval($data)))
                    {
                        
// data looks like an int, treat as timestamp
                        
$data intval($data);
                    }
                    else
                    {
                        
$tz = (XenForo_Visitor::hasInstance() ? XenForo_Locale::getDefaultTimeZone() : null);

                        try
                        {
                            
$date = new DateTime($data$tz);
                            if (!empty(
$filterOptions['dayEnd']))
                            {
                                
$date->setTime(235959);
                            }

                            
$data $date->format('U');
                        }
                        catch (
Exception $e)
                        {
                            
$data 0;
                        }
                    }
                }

                if (!
is_int($data))
                {
                    
$data intval($data);
                }
            break;

            default:
                if (
$filterName instanceof Zend_Validate_Interface)
                {
                    if (
$filterName->isValid($data) === false)
                    {
                        
$data $defaultData;
                    }
                }
                else
                {
                    throw new 
XenForo_Exception("Unknown input type in " __CLASS__ "::" __METHOD__);
                }
        }

        return 
$data;
    }

    
/**
     * Cleans invalid characters out of a string, such as nulls, nbsp, r, etc.
     * Characters may not strictly be invalid, but can cause confusion/bugs.
     *
     * @param string $string
     *
     * @return string
     */
    
public static function cleanString($string)
    {
        
// only cover the BMP as MySQL only supports that
        
$string preg_replace('/[xF0-xF7].../'''$string);
        return 
strtr(strval($string), self::$_strClean);
    }

    
/**
     * Recursively run clean string on all strings in an array
     *
     * @param array $array
     *
     * @return array
     */
    
public static function cleanStringArray(array $array)
    {
        foreach (
$array AS &$v)
        {
            if (
is_string($v))
            {
                
$v self::cleanString($v);
            }
            else if (
is_array($v))
            {
                
$v self::cleanStringArray($v);
            }
        }

        return 
$array;
    }

    
/**
    * Filter an array of items
    *
    * @param array    Key-value pairs with the value being in the format expected by filterSingle. {@link XenForo_Input::filterSingle()}
    *
    * @return array key-value pairs with the cleaned value
    */
    
public function filter(array $filters)
    {
        
$data = array();
        foreach (
$filters AS $variableName => $filterData)
        {
            
$data[$variableName] = $this->filterSingle($variableName$filterData);
        }

        return 
$data;
    }

    
/**
     * Statically filters a piece of data as the requested type.
     *
     * @param mixed $data
     * @param constant $filterName
     * @param array $options
     *
     * @return mixed
     */
    
public static function rawFilter($data$filterName, array $options = array())
    {
        return 
self::_doClean($filterName$options$dataself::$_DEFAULTS[$filterName]);
    }

    
/**
     * Returns true if the given key was included in the request at all.
     *
     * @param string $key
     *
     * @return boolean
     */
    
public function inRequest($key)
    {
        if (
$this->_request)
        {
            return isset(
$this->_request->$key);
        }
        else
        {
            return isset(
$this->_sourceData[$key]);
        }
    }

    
/**
     * Gets all input.
     *
     * @return array
     */
    
public function getInput()
    {
        return 
$this->_request->getParams();
    }

    public function 
__get($key)
    {
        if (
array_key_exists($key$this->_cleanedVariables))
        {
            return 
$this->_cleanedVariables[$key];
        }
    }

    public function 
__isset($key)
    {
        return 
array_key_exists($key$this->_cleanedVariables);
    }
}
Онлайн: 1
Реклама