<?php
 
 
/**
 
 * Usage:
 
 * 
 
 * $id = R\GET::int('id'); //Receive value
 
 * $id = R\REQUEST::defaultValue(0)->intPositive('id'); //Provide default 
 
 *
 
 * GET, POST, COOKIE and REQUEST scopes are supported
 
 *
 
 * Available static methods:
 
 * [method]::exists() - checks if a parameter exists
 
 * scalar() - make sure the parameter is not an array
 
 * trim() - trim the parameter value
 
 * bool() - returns TRUE for 'y', 'on', 1, 'yes'
 
 * numeric() - allows floats, hex
 
 * numericPositive() - make sure the value is postive
 
 * int() - allows long int only (32/64 platform-dependent)
 
 * intPositive() - ensures the value is int greater then 0
 
 * url() - sanitize non-url characters
 
 * arrayOfScalars() - good for checkbox fields
 
 *
 
 * The R\[method]::defaultValue() method allows to define a value returned if the 
 
 * parameter is either not defined or invalid
 
 * 
 
 * You can use this tool with unit tests:
 
 * R\_Request::setMock(new _requestMock(123));
 
 * $id = R\POST::int('id'); //always return 123
 
 * R\_Request::setMock(new _requestMock(array('id'=>256)));
 
 * $value = R\POST::->int('abc'); //NULL
 
 */
 
 
/**
 
 * A namespace for request filter wrapper
 
 * @author http://www.grik.net/
 
 *
 
 */
 
 
namespace R;
 
 
 
/**
 
 * A more convenient interface to filters
 
 * @author gri
 
 * 
 
 */
 
class _Request{
 
    /**
 
     * Default value for the variable
 
     * @var mix
 
     */
 
    protected $default;
 
 
    /**
 
     * the scope constant
 
     * @var int
 
     */
 
    protected $scope;
 
    
 
    /**
 
     * Instance of the class to avoid object duplication
 
     * @var _Request
 
     */
 
    protected static $instance;
 
    
 
    protected function getScope(){
 
        switch (substr(get_called_class(),2)){
 
            case 'GET': return INPUT_GET; 
 
            case 'POST': return INPUT_POST; 
 
            case 'COOKIE': return INPUT_COOKIE;
 
            case 'REQUEST': return INPUT_REQUEST;
 
            default: trigger_error('The scope is not supported',E_USER_ERROR);
 
        }
 
    }
 
    /**
 
     * @return _Request
 
     */
 
    protected static function getInstance(){
 
        if (self::$instance === null){
 
            self::$instance = new _Request();
 
        }
 
        if (self::$instance->scope === null){
 
            self::$instance->scope = self::getScope();
 
        }
 
        return self::$instance;
 
    }
 
    /**
 
     * A way to substitute the data source
 
     * @param g\Filter $mock
 
     */
 
    function setMock(_Request $mock){
 
        self::$instance = $mock;
 
    }
 
    /**
 
     * Provide the value returned if the request parameter does not exist 
 
     *     or does not match the filter criterias 
 
     * @return _Request
 
     */
 
    public static function defaultValue($value){
 
        self::getInstance()->default = $value;
 
        return self::$instance;
 
    }
 
    /**
 
     * @param string $var
 
     * @param array $params
 
     */
 
    protected function filter($var,$params){
 
        $inst = self::getInstance();
 
        if ($inst->scope == INPUT_REQUEST){
 
            $value = null;
 
            $order = ini_get('request_order') ?: ini_get('variables_order');
 
            for ($i=0,$j=strlen($order);$i<$j;++$i){
 
                switch ($order[$i]) {
 
                    case 'G': 
 
                        $scope = INPUT_GET;
 
                        break;
 
                    case 'P': 
 
                        $scope = INPUT_POST;
 
                        break;
 
                    case 'C': 
 
                        $scope = INPUT_COOKIE;
 
                        break;
 
                    default: continue(2);
 
                }
 
                $value = filter_input($scope,$var,$params);
 
                if ($value !== null){
 
                    break;
 
                }
 
            }
 
        }else{
 
            $value = filter_input($inst->scope,$var,$params);
 
        }
 
        if ($inst->default !== null && ($value === null || $value === false)){
 
            $value = $inst->default;
 
        }
 
        $inst->default = $inst->scope = null;
 
        return $value;
 
    }
 
 
    /**
 
     * make sure the request parameter value is not an array
 
     * @param string $var
 
     * @return string
 
     */
 
    static function scalar($var){
 
        return self::filter($var,FILTER_UNSAFE_RAW);
 
    }
 
    /**
 
     * @param string $var
 
     * @return string
 
     */
 
    static function trim($var){
 
        return trim(self::filter($var,FILTER_UNSAFE_RAW));
 
    }
 
    /**
 
     * @param string $var
 
     * @return bool
 
     */
 
    static function bool($var){
 
        return self::filter($var,FILTER_VALIDATE_BOOLEAN);
 
    }
 
    /**
 
     * @param string $var
 
     * @return string
 
     */
 
    static function numeric($var){
 
        $x = self::filter($var,FILTER_VALIDATE_FLOAT);
 
        return ($x === null || $x === false) ? $x : self::trim($var);
 
    }
 
    /**
 
     * @param string $var
 
     * @return int
 
     */
 
    static function int($var){
 
        return self::filter($var,FILTER_VALIDATE_INT);
 
    }
 
    /**
 
     * @param string $var
 
     * @return int
 
     */
 
    static function intPositive($var){
 
        return self::filter($var,FILTER_VALIDATE_INT,array('options'=>array('min_range'=>1)));
 
    }
 
    /**
 
     * @param string $var
 
     * @return string
 
     */
 
    static function numericPositive($var){
 
        if (($x = self::filter($var,FILTER_VALIDATE_FLOAT)) <=0){
 
            $x = false;
 
        }
 
        return ($x === null || $x === false ) ? $x : self::trim($var);
 
    }
 
    /**
 
     * @param string $var
 
     */
 
    static function email($var){
 
        return self::filter($var,FILTER_SANITIZE_EMAIL);
 
    }
 
    /**
 
     * @param string $var
 
     */
 
    static function url($var){
 
        return self::filter($var,FILTER_SANITIZE_URL);
 
    }
 
}
 
class POST extends _Request{}
 
class GET extends _Request{}
 
class COOKIE extends _Request{}
 
class REQUEST extends _Request{}
 
 
/**
 
 * A class to substutute the data returned by the _Request with the given value(s)
 
 * @author gri
 
 *
 
 */
 
class _requestMock extends _Request{
 
    public $data;
 
    /**
 
     * Constructor accepts a scalar or an array
 
     * 
 
     * @param mix $data
 
     */
 
    function __construct($data) {
 
        $this->data = $data;
 
    }
 
    protected function filter($var){
 
        if (is_scalar($this->data)){
 
            return $this->data;
 
        }
 
        if (isset($this->data[$var])){
 
            return $this->data[$var];
 
        }
 
        return null;
 
    }
 
}
 
 
 |