Commit 3214810e authored by romanb's avatar romanb

Temporary fix for #254 until there's a better solution available.

Ticket: 254
parent 239995d3
<?php <?php
/* /*
* $Id$ * $Id$
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* This software consists of voluntary contributions made by many individuals * This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see * and is licensed under the LGPL. For more information, see
* <http://www.phpdoctrine.com>. * <http://www.phpdoctrine.com>.
*/ */
/** /**
* Doctrine_Validator * Doctrine_Validator
* Doctrine_Validator performs validations in record properties * Doctrine_Validator performs validations in record properties
* *
* @package Doctrine * @package Doctrine
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @category Object Relational Mapping * @category Object Relational Mapping
* @link www.phpdoctrine.com * @link www.phpdoctrine.com
* @since 1.0 * @since 1.0
* @version $Revision$ * @version $Revision$
* @author Konsta Vesterinen <kvesteri@cc.hut.fi> * @author Konsta Vesterinen <kvesteri@cc.hut.fi>
*/ */
class Doctrine_Validator class Doctrine_Validator
{ {
/** /**
* @var array $validators an array of validator objects * @var array $validators an array of validator objects
*/ */
private static $validators = array(); private static $validators = array();
/** /**
* @var Doctrine_Null $null a Doctrine_Null object used for extremely fast * @var Doctrine_Null $null a Doctrine_Null object used for extremely fast
* null value testing * null value testing
*/ */
private static $null; private static $null;
/** /**
* initNullObject * initNullObject
* *
* @param Doctrine_Null $null * @param Doctrine_Null $null
* @return void * @return void
*/ */
public static function initNullObject(Doctrine_Null $null) public static function initNullObject(Doctrine_Null $null)
{ {
self::$null = $null; self::$null = $null;
} }
/** /**
* returns a validator object * returns a validator object
* *
* @param string $name * @param string $name
* @return Doctrine_Validator_Interface * @return Doctrine_Validator_Interface
*/ */
public static function getValidator($name) public static function getValidator($name)
{ {
if ( ! isset(self::$validators[$name])) { if ( ! isset(self::$validators[$name])) {
$class = "Doctrine_Validator_".ucwords(strtolower($name)); $class = "Doctrine_Validator_".ucwords(strtolower($name));
if (class_exists($class)) { if (class_exists($class)) {
self::$validators[$name] = new $class; self::$validators[$name] = new $class;
} else { } else {
throw new Doctrine_Exception("Validator named '$name' not availible."); throw new Doctrine_Exception("Validator named '$name' not availible.");
} }
} }
return self::$validators[$name]; return self::$validators[$name];
} }
/** /**
* validates a given record and saves possible errors * validates a given record and saves possible errors
* in Doctrine_Validator::$stack * in Doctrine_Validator::$stack
* *
* @param Doctrine_Record $record * @param Doctrine_Record $record
* @return void * @return void
*/ */
public function validateRecord(Doctrine_Record $record) public function validateRecord(Doctrine_Record $record)
{ {
$columns = $record->getTable()->getColumns(); $columns = $record->getTable()->getColumns();
$component = $record->getTable()->getComponentName(); $component = $record->getTable()->getComponentName();
$errorStack = $record->getErrorStack(); $errorStack = $record->getErrorStack();
// if record is transient all fields will be validated // if record is transient all fields will be validated
// if record is persistent only the modified fields will be validated // if record is persistent only the modified fields will be validated
$data = ($record->exists()) ? $record->getModified() : $record->getData(); $data = ($record->exists()) ? $record->getModified() : $record->getData();
$err = array(); $err = array();
foreach ($data as $key => $value) { foreach ($data as $key => $value) {
if ($value === self::$null) if ($value === self::$null)
$value = null; $value = null;
elseif ($value instanceof Doctrine_Record) elseif ($value instanceof Doctrine_Record)
$value = $value->getIncremented(); $value = $value->getIncremented();
$column = $columns[$key]; $column = $columns[$key];
if ($column[0] == "enum") { if ($column[0] == "enum") {
$value = $record->getTable()->enumIndex($key, $value); $value = $record->getTable()->enumIndex($key, $value);
if ($value === false) { if ($value === false) {
$errorStack->add($key, 'enum'); $errorStack->add($key, 'enum');
continue; continue;
} }
} }
if ($record->getTable()->getAttribute(Doctrine::ATTR_AUTO_LENGTH_VLD)) { if ($record->getTable()->getAttribute(Doctrine::ATTR_AUTO_LENGTH_VLD)) {
if (!$this->validateLength($column, $key, $value)) { if (!$this->validateLength($column, $key, $value)) {
$errorStack->add($key, 'length'); $errorStack->add($key, 'length');
continue; continue;
} }
} }
if ( ! is_array($column[2])) { if ( ! is_array($column[2])) {
$e = explode("|",$column[2]); $e = explode("|",$column[2]);
} else { } else {
$e = $column[2]; $e = $column[2];
} }
foreach ($e as $k => $arg) { foreach ($e as $k => $arg) {
if (is_string($k)) { if (is_string($k)) {
$name = $k; $name = $k;
$args = $arg; $args = $arg;
} else { } else {
$args = explode(":",$arg); $args = explode(":",$arg);
$name = array_shift($args); $name = array_shift($args);
if ( ! isset($args[0])) { if ( ! isset($args[0])) {
$args[0] = ''; $args[0] = '';
} }
} }
if (empty($name) if (empty($name)
|| $name == 'primary' || $name == 'primary'
|| $name == 'protected' || $name == 'protected'
|| $name == 'autoincrement' || $name == 'autoincrement'
|| $name == 'default' || $name == 'default'
) { ) {
continue; continue;
} }
if (strtolower($name) == 'length') { if (strtolower($name) == 'length') {
if (!$record->getTable()->getAttribute(Doctrine::ATTR_AUTO_LENGTH_VLD)) { if (!$record->getTable()->getAttribute(Doctrine::ATTR_AUTO_LENGTH_VLD)) {
if (!$this->validateLength($column, $key, $value)) { if (!$this->validateLength($column, $key, $value)) {
$errorStack->add($key, 'length'); $errorStack->add($key, 'length');
} }
} }
continue; continue;
} }
if (strtolower($name) == 'type') { if (strtolower($name) == 'type') {
if (!$record->getTable()->getAttribute(Doctrine::ATTR_AUTO_TYPE_VLD)) { if (!$record->getTable()->getAttribute(Doctrine::ATTR_AUTO_TYPE_VLD)) {
if ( ! self::isValidType($value, $column[0])) { if ( ! self::isValidType($value, $column[0])) {
$errorStack->add($key, 'type'); $errorStack->add($key, 'type');
} }
} }
continue; continue;
} }
$validator = self::getValidator($name); $validator = self::getValidator($name);
if ( ! $validator->validate($record, $key, $value, $args)) { if ( ! $validator->validate($record, $key, $value, $args)) {
$errorStack->add($key, $name); $errorStack->add($key, $name);
//$err[$key] = 'not valid'; //$err[$key] = 'not valid';
// errors found quit validation looping for this column // errors found quit validation looping for this column
//break; //break;
} }
} }
if ($record->getTable()->getAttribute(Doctrine::ATTR_AUTO_TYPE_VLD)) { if ($record->getTable()->getAttribute(Doctrine::ATTR_AUTO_TYPE_VLD)) {
if ( ! self::isValidType($value, $column[0])) { if ( ! self::isValidType($value, $column[0])) {
$errorStack->add($key, 'type'); $errorStack->add($key, 'type');
continue; continue;
} }
} }
} }
} }
/** /**
* Enter description here... * Enter description here...
* *
*/ */
private function validateLength($column, $key, $value) private function validateLength($column, $key, $value)
{ {
if ($column[0] == "array" || $column[0] == "object") { if($column[0] == "timestamp") {
$length = strlen(serialize($value)); return true;
} else { }
$length = strlen($value); else if ($column[0] == "array" || $column[0] == "object") {
} $length = strlen(serialize($value));
} else {
if ($length > $column[1]) { $length = strlen($value);
return false; }
}
return true; if ($length > $column[1]) {
} return false;
/** }
* whether or not this validator has errors return true;
* }
* @return boolean /**
*/ * whether or not this validator has errors
public function hasErrors() *
{ * @return boolean
return (count($this->stack) > 0); */
} public function hasErrors()
/** {
* converts a doctrine type to native php type return (count($this->stack) > 0);
* }
* @param $doctrineType /**
* @return string * converts a doctrine type to native php type
*/ *
public static function phpType($doctrineType) * @param $doctrineType
{ * @return string
switch ($doctrineType) { */
case 'enum': public static function phpType($doctrineType)
return 'integer'; {
case 'blob': switch ($doctrineType) {
case 'clob': case 'enum':
case 'mbstring': return 'integer';
case 'timestamp': case 'blob':
case 'date': case 'clob':
case 'gzip': case 'mbstring':
return 'string'; case 'timestamp':
break; case 'date':
default: case 'gzip':
return $doctrineType; return 'string';
} break;
} default:
/** return $doctrineType;
* returns whether or not the given variable is }
* valid type }
* /**
* @param mixed $var * returns whether or not the given variable is
* @param string $type * valid type
* @return boolean *
*/ * @param mixed $var
public static function isValidType($var, $type) * @param string $type
{ * @return boolean
if ($type == 'boolean') */
return true; public static function isValidType($var, $type)
{
$looseType = self::gettype($var); if ($type == 'boolean')
$type = self::phpType($type); return true;
switch ($looseType) { $looseType = self::gettype($var);
case 'float': $type = self::phpType($type);
case 'double':
case 'integer': switch ($looseType) {
if ($type == 'string' || $type == 'float') case 'float':
return true; case 'double':
case 'string': case 'integer':
case 'array': if ($type == 'string' || $type == 'float')
case 'object': return true;
return ($type === $looseType); case 'string':
break; case 'array':
case 'NULL': case 'object':
return true; return ($type === $looseType);
break; break;
}; case 'NULL':
} return true;
/** break;
* returns the type of loosely typed variable };
* }
* @param mixed $var /**
* @return string * returns the type of loosely typed variable
*/ *
public static function gettype($var) * @param mixed $var
{ * @return string
$type = gettype($var); */
switch ($type) { public static function gettype($var)
case 'string': {
if (preg_match("/^[0-9]+$/",$var)) { $type = gettype($var);
return 'integer'; switch ($type) {
} elseif (is_numeric($var)) { case 'string':
return 'float'; if (preg_match("/^[0-9]+$/",$var)) {
} else { return 'integer';
return $type; } elseif (is_numeric($var)) {
} return 'float';
break; } else {
default: return $type;
return $type; }
}; break;
} default:
} return $type;
};
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment