<?php
 
/**
 
 * @author Thomas Schaefer
 
 * @mail [email protected]
 
*/
 
class TypeSafeStruct extends TypedStruct
 
{
 
 
    protected $database = "";
 
    protected $table = "";
 
 
    public function getDatabase() {
 
        return $this->database;
 
    }
 
 
    public function getTable() {
 
        return $this->table;
 
    }
 
 
 
    /**
 
     * isValid
 
     *
 
     * @param string $k column name
 
     * @param mixed $v column value
 
     * @param string $type column type
 
     * @return mixed bool|Exception
 
     *
 
     */
 
    public function isValid($k, $v, $type) {
 
        if (!isset($v)) return false;
 
        if (is_null($v)) return false;
 
        switch ($type) {
 
            case "int":
 
            case "integer":
 
                return is_numeric($v);
 
            case "timestamp":
 
                return (strtotime($v)>0?true:false);
 
            case "decimal":
 
            case "float":
 
            case "real":
 
                return is_float($v);
 
            case "string":
 
                return is_string($v);
 
            case "bool":
 
                return is_bool($v);
 
            default:
 
                throw new Exception(sprintf("'%s'.'%s' has invalid type: '%s'", get_class($this), $k, $type));
 
        }
 
    }
 
 
    /**
 
     * __call
 
     *
 
     * @param string $name method name
 
     * @param array $params This is a description
 
     * @return mixed This is the return value description
 
     *
 
     */
 
    public function __call($name, $params){
 
 
        $methodObject = self::getMethodType($name);
 
        $methodType = $methodObject["type"];
 
        $name = $methodObject["name"];
 
 
        # begin dynamic methods
 
        switch($methodType) {
 
            case "get" :
 
 
                if (!$this->hasProperty(self::underscore($name))) {
 
                    throw new Exception(sprintf("'%s' has no property '%s'", get_class($this), $name));
 
                }
 
                $propType = $this->getPropertyType(self::underscore($name));
 
                return $this->{$propType."_".self::underscore($name)};
 
                break;
 
            case "set" :
 
                if (!$this->hasProperty(self::underscore($name))) {
 
                    throw new Exception(sprintf("'%s' has no property '%s'", get_class($this), self::underscore($name)));
 
                }
 
                if (!($propType = $this->getPropertyType(self::underscore($name)))) {
 
                    throw new Exception(sprintf("'%s'.'%s' has no type set", get_class($this), self::underscore($name)));
 
                }
 
                if (!$this->isValid($name, $params[0], $propType)) {
 
                    throw new Exception(sprintf("'%s'.'%s' = %s is not valid for '%s'", get_class($this), self::underscore($name), $params[0], $propType));
 
                }
 
 
                $this->{$propType."_".self::underscore($name)} = $params[0];
 
 
                return $this;
 
        }
 
        # end dynamic methods
 
 
    }
 
 
    /**
 
     * getMethodType
 
     * @desc extract method informations
 
     * @param string $string
 
     */
 
    private static function getMethodType($string) {
 
        $tmp = explode("_", self::underscore($string));
 
        $methodType = array();
 
        $methodType["length"] = strlen($tmp[0]);
 
        $methodType["type"] = $tmp[0];
 
        $methodType["name"] = substr($string, $methodType["length"]);
 
        return $methodType;
 
    }
 
 
    public static function underscore($word = null) {
 
        $tmp = self :: replace($word, array (
 
                    '/([A-Z]+)([A-Z][a-z])/' => '\\1_\\2',
 
                    '/([a-z\d])([A-Z])/' => '\\1_\\2'
 
                    ));
 
        return strtolower($tmp);
 
    }
 
 
    protected static function replace($search, $replacePairs) {
 
        return preg_replace(array_keys($replacePairs), array_values($replacePairs), $search);
 
    }
 
 
}
 
 
 |