<?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;
}
}
|