<?php
/*
** This file is part of Ciwii.
**
** Ciwii is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** Ciwii is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with Ciwii. If not, see <http://www.gnu.org/licenses/>.
*/
/* (desc)
** This object is a special struct-object
** It can save different properties with binding types and
** absolute values, so if default value is set, null should
** get returned
**
** To use this object create a new object-instance and set
** properties:
**
** $var = new StructObject(
** "property1:string = 'foo',
** property2A:string = 'bar'"
** );
**
** So $var->property1 and $var->property2 are set. Both can
** handle only strings. If you give them something different
** an error will apear.
** If you call $var->property2A, this property gets checked.
** Whether it has the default value, null gets returned.
*/
class StructObject
{
/*
** @property Containing all other properties of StructObject
*/
private $propertyBox=array();
/*
** @magic
** @param str $vars Contains variables to set up
*/
public function __construct($vars)
{
//Exploding variables by comma
$vars = explode(',', $vars);
$varsNum = count($vars);
for ($i=0; $i<$varsNum; $i++)
{ //Fill $this->propertyBox by parsing every part
$var = trim($vars[$i]);
//Split variable from default-value
$tmp = explode('=', $var, 2);
$varName = trim($tmp[0]);
$varValue = '';
$absolute = false;
if (isset($tmp[1])) $varValue = trim($tmp[1]);
if (substr($varValue, 0, 1) == "'" && substr($varValue, -1) == "'")
$varValue = stripslashes(substr($varValue, 1, -1));
//Get types
$tmp = explode(':', $varName);
$varName = trim(array_shift($tmp));
$varTypes = $tmp;
if (substr($varName, -1) == 'A')
{
$absolute = true; //Use absolute variant
$varName = substr($varName, 0, -1);
}
//Adding property to $this->propertyBox
$this->_addVariable($varName, $varValue, $varTypes, $absolute);
}
}
/*
** @magic
** @param str $label
*/
public function __get($label)
{
//Check if absolute-request
if (substr($label, -1) == 'A')
{
$label = substr($label, 0, -1);
//Check if property exists
if (array_key_exists($label, $this->propertyBox))
{
//Check if absolute-varant is enabled
if ($this->propertyBox[$label][2] !== false)
{
//Check if default-value is given
if ($this->propertyBox[$label][0] == $this->propertyBox[$label][2][1])
return null;
else
return $this->propertyBox[$label][0];
}
else
return $this->propertyBox[$label][0];
}
else
return null;
}
//If normal-request
return array_key_exists($label, $this->propertyBox) ? $this->propertyBox[$label][0]:null;
}
/*
** @magic Try to change property
** @param str $label
** @param mix $value
*/
public function __set($label, $value)
{
if (!array_key_exists($label, $this->propertyBox))
die('<br /><b>Error:</b> Property '.$label.' not registered');
//Check if property has to have a strict type
if (count($this->propertyBox[$label][1]) > 0)
{
//Check if property would get the right type
if (!$this->_checkType($value, $this->propertyBox[$label][1]))
{
$type = $this->_whatType($value);
die('<br /><b>Error:</b> Given type '.$type.' not allowed for '.$label.$this->_getTypes($label).'.');
}
}
$this->propertyBox[$label][0] = $value;
}
/*
** @magic
** @param str $label
*/
public function __isset($label)
{
if (array_key_exists($label, $this->propertyBox))
return true;
else
return false;
}
/*
** @magic Do not allow anybody to remove a property
** @param str $label
*/
public function __unset($label)
{
return false;
}
/*
** @method void Adds property to class
** @param str $label Property-name
** @param str $defaultValue
** @param array $defaultTypes
*/
private function _addVariable($label, $defaultValue='', $defaultTypes=array(), $absoluteVariant=false)
{
$typesNum = count($defaultTypes);
$types = array('boolean', 'integer', 'float', 'string', 'array', 'object', 'null');
//Check types
for ($i=0; $i<$typesNum; $i++)
{
$defaultTypes[$i] = trim($defaultTypes[$i]);
$type = '';
//Check if strict class is needed and look if it exists
if (substr($defaultTypes[$i], 0, 7) == 'object[' &&
substr($defaultTypes[$i], -1) == ']')
{
$objectName = substr($defaultTypes[$i], 7, -1);
$defaultTypes[$i] = array('object', $objectName);
$type = 'object';
}
else
$type = $defaultTypes[$i];
if (!in_array($type, $types))
die('<br /><b>Error:</b> Wrong type set for '.htmlentities($label).' ('.htmlentities($type).')');
}
if (!isset($defaultTypes[0]))
$defaultValue = (string)$defaultValue;
else
{ //Set default values
if (is_array($defaultTypes[0]) == true && $defaultTypes[0][0] == 'object')
{
//Check if class exists
if (!class_exists($defaultTypes[0][1]))
die('<br /><b>Error:</b> Wrong type set ('.$defaultTypes[0][1].')');
$defaultValue = new $defaultTypes[0][1];
}
elseif ($defaultTypes[0] == 'object')
$defaultValue = null;
elseif ($defaultTypes[0] == 'array')
$defaultValue = array();
else
settype($defaultValue, $defaultTypes[0]);
}
$label = trim($label);
$absolute = false;
if ($absoluteVariant)
$absolute = array(true, $defaultValue);
$this->propertyBox[$label] = array($defaultValue, $defaultTypes, $absolute);
}
/*
** @method bol Checks, if type is allowed
** @param str $type Typename
** @param array &$property
*/
private function _checkType(&$obj, &$property)
{
$type = $this->_whatType($obj);
$typesNum = count($property);
for ($i=0; $i<$typesNum; $i++)
{
$t = &$property[$i];
if (is_array($t))
{
if ($type == $t[0] && get_class($obj) == $t[1])
return true;
}
elseif ($t == $type)
return true;
}
return false;
}
/*
** @method str Returns all allowed types of property
** @param str $label
*/
private function _getTypes($label)
{
if (!array_key_exists($label, $this->propertyBox))
return false;
$obj = &$this->propertyBox[$label];
$typesNum = count($obj[1]);
$output = '';
for ($i=0; $i<$typesNum; $i++)
{
$t = &$obj[1][$i];
if (is_array($t))
$output .= ':object['.$t[1].']';
else
$output .= ':'.$t;
}
return $output;
}
/*
** @method str Faster version of php's default gettype
** @param mix &$var
*/
private function _whatType(&$var)
{
if (is_int($var))
return 'integer';
elseif (is_bool($var))
return 'boolean';
elseif (is_float($var))
return 'float';
elseif (is_string($var))
return 'string';
elseif (is_array($var))
return 'array';
elseif (is_null($var))
return 'null';
elseif (is_object($var))
return 'object';
elseif (is_resource($var))
return 'resource';
else
return 'unknown';
}
}
?>
|