<?php
/**
* the base constraint, restricts input to a specific type, and nullability.
* <code>
* <pre>
* private static $_myConstraint = false;
*
* public function __construct()
* {
* // create the constraint as a static, we only need one for all call references
* if (self::$_myConstraint == false)
* self::$_myConstraint = new Constraint('a constraint', integer, false);
* }
* public function setSomeThing($data)
* {
* self::$_myConstraint->validate($data); // throws BSException.php if $data is not type integer and not null
* $this->_someInt = $data
* }
* </pre>
* </code>
*
* @author Cory
* @package constraints
* @property string $_name the name of this constriant, for humans
* @property string $_type the type of object to accpet, either from get_type or instanceOf
* @property boolean $_nullAble true if the object may be null
* @property boolean $_isNull true if this constrinat check, tested for nullablility and
* and it was null and the null is allowed, this can be used by subclasses for
* testing null
*/
if (!defined('ConstraintException')) {
class ConstraintException extends RuntimeException {
}
}
class Constraint
{
protected $_name;
protected $_type;
protected $_nullAble;
protected $_isNull;
/**
* build a new simple Contraint for objects and types
*
* @param String $name the name of the constraint
* @param String $type the PHP name for the type as returned by instanceof or gettype()
* @param Boolean $nullAble true if the paramater may be null
*/
public function __construct($name = false, $type = false, $nullAble = false)
{
if (!$type)
throw new RuntimeException('Can not create a constraint without an alpanumeric type name');
$this->_name = $name;
$this->_type = $type;
$this->_nullAble = $nullAble;
}
/**
* validate that the passed paramater matches the constraint
*
* @param mixed $param the paramater to test
* @return Boolean true if validation succeeds
*/
public function validate($param, $message = false)
{
$param = trim($param);
if ($param !== 0 && ($this->_nullAble && (!isset($param) || !$param || $param == '')))
{
$this->_isNull = true;
return true;
}
$res = '';
if (!$this->_nullAble && (!isset($param)))
$res = ($message) ? $message : 'constraint: ' . $this->_name . ' may not be null';
if (is_object($param) && !$param instanceof $this->_type)
$res = ($message) ? $message : 'constraint: ' . $this->_name . ' may not be type: ' . $this->_type;
switch ($this->_type)
{
case 'integer':
if (!is_numeric($param))
$res = ($message) ? $message : $param . ' not numeric constraint: ' . $this->_name . ' must be type: ' . $this->_type;
break;
case 'string':
case 'datetime':
if (!is_string($param))
$res = ($message) ? $message : $param . ' not string constraint: ' . $this->_name . ' must be type: ' . $this->_type;
break;
case 'boolean':
if (!is_bool($param) && $param != true && $param != false)
$res = ($message) ? $message : $param . ' not bool constraint: ' . $this->_name . ' must be type: ' . $this->_type;
break;
case 'float':
if (!is_float($param) && !is_numeric($param))
$res = ($message) ? $message : $param . ' not float constraint: ' . $this->_name . ' must be type: ' . $this->_type;
break;
default:
$res = ($message) ? $message : $param . ' constraint: ' . $this->_name . ' must be type: ' . $this->_type;
}
if ($res)
{
throw new ConstraintException($res);
}
return true;
}
}