diff --git a/lib/Cake/Model/Model.php b/lib/Cake/Model/Model.php index 62ac03e18f4..9de8f322aa1 100644 --- a/lib/Cake/Model/Model.php +++ b/lib/Cake/Model/Model.php @@ -2120,7 +2120,7 @@ public function saveMany($data = null, $options = array()) { * Otherwise: array similar to the $data array passed, but values are set to true/false * depending on whether each record validated successfully. */ - public function validateMany($data, $options = array()) { + public function validateMany(&$data, $options = array()) { return $this->validator()->validateMany($data, $options); } @@ -2300,63 +2300,7 @@ public function saveAssociated($data = null, $options = array()) { * depending on whether each record validated successfully. */ public function validateAssociated(&$data, $options = array()) { - $options = array_merge(array('atomic' => true, 'deep' => false), $options); - $this->validationErrors = $validationErrors = $return = array(); - if (!($this->create($data) && $this->validates($options))) { - $validationErrors[$this->alias] = $this->validationErrors; - $return[$this->alias] = false; - } else { - $return[$this->alias] = true; - } - - if (empty($options['deep'])) { - $data = $this->data; - } else { - $modelData = $this->data; - $recordData = $modelData[$this->alias]; - unset($modelData[$this->alias]); - $data = $modelData + array_merge($data, $recordData); - } - - $associations = $this->getAssociated(); - foreach ($data as $association => &$values) { - $validates = true; - if (isset($associations[$association])) { - if (in_array($associations[$association], array('belongsTo', 'hasOne'))) { - if ($options['deep']) { - $validates = $this->{$association}->validateAssociated($values, $options); - } else { - $validates = $this->{$association}->create($values) !== null && $this->{$association}->validates($options); - } - if (is_array($validates)) { - if (in_array(false, $validates, true)) { - $validates = false; - } else { - $validates = true; - } - } - $return[$association] = $validates; - } elseif ($associations[$association] === 'hasMany') { - $validates = $this->{$association}->validateMany($values, $options); - $return[$association] = $validates; - } - if (!$validates || (is_array($validates) && in_array(false, $validates, true))) { - $validationErrors[$association] = $this->{$association}->validationErrors; - } - } - } - - $this->validationErrors = $validationErrors; - if (isset($validationErrors[$this->alias])) { - $this->validationErrors = $validationErrors[$this->alias]; - } - if (!$options['atomic']) { - return $return; - } - if ($return[$this->alias] === false || !empty($this->validationErrors)) { - return false; - } - return true; + return $this->validator()->validateAssociated($data, $options); } /** @@ -3432,7 +3376,7 @@ public function validator($instance = null) { return $this->_validator = $instance; } - if (is_null($instance) && is_null($this->validatorClass)) { + if (is_null($instance)) { $this->_validator = new ModelValidator($this); } diff --git a/lib/Cake/Model/ModelValidator.php b/lib/Cake/Model/ModelValidator.php index e0a5d83065c..be8d159215b 100644 --- a/lib/Cake/Model/ModelValidator.php +++ b/lib/Cake/Model/ModelValidator.php @@ -101,15 +101,18 @@ public function validates($options = array()) { * - fieldList: Equivalent to the $fieldList parameter in Model::save() * - deep: If set to true, not only directly associated data , but deeper nested associated data is validated as well. * + * Warning: This method could potentially change the passed argument `$data`, + * If you do not want this to happen, make a copy of `$data` before passing it + * to this method + * * @param array $data Record data to validate. This should be an array indexed by association name. * @param array $options Options to use when validating record data (see above), See also $options of validates(). * @return array|boolean If atomic: True on success, or false on failure. * Otherwise: array similar to the $data array passed, but values are set to true/false * depending on whether each record validated successfully. */ - public function validateAssociated($data, $options = array()) { + public function validateAssociated(&$data, $options = array()) { $model = $this->getModel(); - $options = array_merge(array('atomic' => true, 'deep' => false), $options); $model->validationErrors = $validationErrors = $return = array(); if (!($model->create($data) && $model->validates($options))) { @@ -118,8 +121,18 @@ public function validateAssociated($data, $options = array()) { } else { $return[$model->alias] = true; } + + if (empty($options['deep'])) { + $data = $model->data; + } else { + $modelData = $model->data; + $recordData = $modelData[$model->alias]; + unset($modelData[$model->alias]); + $data = $modelData + array_merge($data, $recordData); + } + $associations = $model->getAssociated(); - foreach ($data as $association => $values) { + foreach ($data as $association => &$values) { $validates = true; if (isset($associations[$association])) { if (in_array($associations[$association], array('belongsTo', 'hasOne'))) { @@ -168,6 +181,10 @@ public function validateAssociated($data, $options = array()) { * - fieldList: Equivalent to the $fieldList parameter in Model::save() * - deep: If set to true, all associated data will be validated as well. * + * Warning: This method could potentially change the passed argument `$data`, + * If you do not want this to happen, make a copy of `$data` before passing it + * to this method + * * @param array $data Record data to validate. This should be a numerically-indexed array * @param array $options Options to use when validating record data (see above), See also $options of validates(). * @return boolean True on success, or false on failure. @@ -175,15 +192,16 @@ public function validateAssociated($data, $options = array()) { * Otherwise: array similar to the $data array passed, but values are set to true/false * depending on whether each record validated successfully. */ - public function validateMany($data, $options = array()) { + public function validateMany(&$data, $options = array()) { $model = $this->getModel(); $options = array_merge(array('atomic' => true, 'deep' => false), $options); $model->validationErrors = $validationErrors = $return = array(); - foreach ($data as $key => $record) { + foreach ($data as $key => &$record) { if ($options['deep']) { $validates = $model->validateAssociated($record, $options); } else { $validates = $model->create($record) && $model->validates($options); + $data[$key] = $model->data; } if ($validates === false || (is_array($validates) && in_array(false, $validates, true))) { $validationErrors[$key] = $model->validationErrors;