From e11424282477f447e9336784a0d96ae433fbb914 Mon Sep 17 00:00:00 2001 From: Peter Date: Tue, 7 Mar 2017 12:58:48 +0100 Subject: [PATCH] breaking changes --- src/Components/Attribute.php | 17 ++++------ src/Components/Model.php | 64 +++++++++++++++++++++++++++++++----- src/Components/Validator.php | 44 ++++++++++++++++++------- 3 files changed, 94 insertions(+), 31 deletions(-) diff --git a/src/Components/Attribute.php b/src/Components/Attribute.php index d2700ee..d643c72 100644 --- a/src/Components/Attribute.php +++ b/src/Components/Attribute.php @@ -17,7 +17,7 @@ class Attribute { /** * @var Validator */ - private $_validator; + public $validator; /** * Attribute constructor. @@ -26,23 +26,18 @@ class Attribute { * @param $rule */ public function __construct(Model $owner, $rule) { - $this->_validator = new Validator($owner, $rule); + $this->validator = new Validator($owner, $rule); $this->key = current($rule); - $this->value = $this->_validator->getNewValue(); + if ($this->validator->getRelationType() === Validator::TYPE_MANY) { + $this->value = new \ArrayObject(); + } } /** * Runs the validation for this attribute */ public function validate() { - $this->_validator->run(); - } - - /** - * @return Validator - */ - public function getValidator() { - return $this->_validator; + $this->validator->run(); } } \ No newline at end of file diff --git a/src/Components/Model.php b/src/Components/Model.php index 40b566b..5072672 100644 --- a/src/Components/Model.php +++ b/src/Components/Model.php @@ -36,8 +36,8 @@ public static function model() { * @return mixed */ public function __get($name) { - if (isset($this->attributes[$name])) { - return $this->attributes[$name]->value; + if ($this->getAttribute($name, true)) { + return $this->getAttribute($name)->value; } return null; @@ -50,11 +50,11 @@ public function __get($name) { * @param $value */ public function __set($name, $value) { - if (isset($this->attributes[$name])) { - if ($this->attributes[$name] instanceof \ArrayObject) { - $this->attributes[$name]->value[] = $value; + if ($this->getAttribute($name)) { + if ($this->getAttribute($name) instanceof \ArrayObject) { + $this->getAttribute($name)->value[] = $value; } else { - $this->attributes[$name]->value = $value; + $this->getAttribute($name)->value = $value; } } } @@ -128,10 +128,53 @@ public function setAttributes($data) { $data = $data->getAttributes(); } foreach ($data as $key => $value) { - $this->$key = $value; + if ($this->getAttributeRelation($key) === Validator::TYPE_MANY) { + foreach ($value as $subValue) { + $item = $this->getAttribute($key)->validator->getNewModel(); + $item->setAttributes($subValue); + $this->{$key}[] = $item; + } + } else if ($this->getAttributeRelation($key) === Validator::TYPE_HAS_ONE) { + $newModel = $this->getAttribute($key)->validator->getNewModel(); + $newModel->setAttributes($value); + $this->{$key} = $newModel; + } else { + $this->{$key} = $value; + } } } + /** + * @param $key + * + * @return integer + */ + protected function getAttributeRelation($key) { + if (isset($this->attributes[$this->getFormattedKey($key, true)])) { + $attribute = $this->attributes[$this->getFormattedKey($key, true)]; + + return $attribute->validator->getRelationType(); + } + + return Validator::TYPE_VALUE; + } + + /** + * @param $key + * + * @return Attribute|bool + */ + protected function getAttribute($key) { + if (isset($this->attributes[$this->getFormattedKey($key, true)])) { + return $this->attributes[$this->getFormattedKey($key, true)]; + } + + return false; + } + + /** + * @return array + */ protected function getMap() { return []; } @@ -140,11 +183,14 @@ protected function getMap() { * Returns the mapped key * * @param $key + * @param $flip * * @return mixed */ - protected function getFormattedKey($key) { - return array_key_exists($key, $this->getMap()) ? $this->getMap()[$key] : $key; + protected function getFormattedKey($key, $flip = false) { + $keys = (($flip) ? array_flip($this->getMap()) : $this->getMap()); + + return array_key_exists($key, $keys) ? $keys[$key] : $key; } /** diff --git a/src/Components/Validator.php b/src/Components/Validator.php index 43f7a8c..cc2c555 100644 --- a/src/Components/Validator.php +++ b/src/Components/Validator.php @@ -2,6 +2,8 @@ namespace Afosto\Bp\Components; +use Afosto\Bp\Exceptions\ValidationException; + class Validator { /** @@ -55,6 +57,12 @@ class Validator { */ private $_type; + /** + * Full namespaced path to the new model + * @var string + */ + private $_modelPath; + /** * Validator constructor. * @@ -68,13 +76,27 @@ public function __construct(Model $owner, array $rule) { list($key, $type, $required, $validation) = $rule; $this->key = $key; $this->_owner = $owner; + $this->_type = $type; + if (is_numeric($validation)) { $this->_callable = [$this->_owner, 'validateMaxLength']; $this->_callableParams = [$validation, $this->key]; - } else if ($validation !== null && ($this->_getRelationType() == self::TYPE_VALUE || $this->_getRelationType() == self::TYPE_HAS_ONE)) { + } else if ($validation !== null && ($this->getRelationType() == self::TYPE_VALUE || $this->getRelationType() == self::TYPE_HAS_ONE)) { $this->_callable = [$this->_owner, $validation]; } - $this->_type = $type; + + if ($this->getRelationType() != self::TYPE_VALUE) { + $reflector = new \ReflectionClass($this->_owner); + if (substr($type, 0, 1) === '\\') { + $this->_modelPath = $this->_type; + } else { + if (substr($type, -2) === '[]') { + $this->_modelPath = $reflector->getNamespaceName() . '\\' . substr($this->_type, 0, -2); + } else { + $this->_modelPath = $reflector->getNamespaceName() . '\\' . $this->_type; + } + } + } $this->_required = (bool)$required; } @@ -93,21 +115,22 @@ public function run() { } /** - * @return \ArrayObject|null + * @return Model + * @throws ValidationException */ - public function getNewValue() { - if ($this->_getRelationType() == self::TYPE_MANY) { - return new \ArrayObject(); + public function getNewModel() { + if (class_exists($this->_modelPath)) { + return new $this->_modelPath; } - return null; + throw new ValidationException('Model ' . $this->_modelPath . ' not found'); } /** - * @return int + * @return integer */ - public function _getRelationType() { - if (in_array($this->_type, ['string', 'integer', 'float', 'boolean'])) { + public function getRelationType() { + if (in_array($this->_type, ['string', 'integer', 'float', 'boolean', '\DateTime'])) { return self::TYPE_VALUE; } else if (substr($this->_type, -2) == '[]') { return self::TYPE_MANY; @@ -115,5 +138,4 @@ public function _getRelationType() { return self::TYPE_HAS_ONE; } } - } \ No newline at end of file