public function validate(array $attributeNames, array $rules) { $messages = []; $errors = $this->model->getErrors(); if (isset($rules['messages'])) { $messages = $rules['messages']; } foreach ($attributeNames as $name) { $placeholders = []; if (isset($rules['placeholders'])) { $placeholders = $rules['placeholders']; } if ($this->useLabelsAsPlaceholders && !isset($placeholders['name'])) { if (($label = $this->model->attributeLabels()) && isset($label[$name])) { $placeholders['name'] = $label[$name]; } } foreach ($rules as $key => $ruleName) { if ($key === 'placeholders' || $key === 'messages' || $key === 'one' || $key === 'when') { continue; } if ($ruleName === 'one') { $rules[$ruleName] = 0; continue; } $args = []; if (is_string($key)) { if (is_callable($ruleName)) { $ruleName = call_user_func($ruleName, $this->model); } if (!is_array($ruleName)) { throw new ModelException('Arguments must be `array`'); } $args = $ruleName; $ruleName = $key; } $onlySanitize = $this->isOnlySanitize($ruleName); // closure if ($ruleName instanceof \Closure) { array_unshift($args, $this->model->{$name}, $name); call_user_func_array(\Closure::bind($ruleName, $this->model), $args); continue; } // method if (method_exists($this->model, $ruleName)) { array_unshift($args, $this->model->{$name}, $name); call_user_func_array([$this->model, $ruleName], $args); continue; } /** @var ModelValidate $validate */ $validate = clone Instance::ensure($this->validate, ModelValidate::className()); /** @var ModelSanitize $sanitize */ $sanitize = clone Instance::ensure($this->sanitize, ModelSanitize::className()); if (!$validate->existsRule($ruleName) && !$sanitize->existsRule($ruleName)) { throw new ModelException("Unknown rule: {$ruleName}"); } if (!$onlySanitize && $validate->existsRule($ruleName)) { $this->validateInternal($validate, $ruleName, $name, $args, $placeholders, $messages); } if ($this->model->hasErrors()) { continue; } $this->sanitizeInternal($sanitize, $ruleName, $name, $args); } if (isset($rules['one'])) { if ((is_int($rules['one']) || $rules['one'] === $name) && $errors !== $this->model->getErrors()) { return false; } } } if (isset($rules['when']) && $errors === $this->model->getErrors()) { return $this->validate($attributeNames, $rules['when']); } return true; }
/** * Serializes the validation errors in a model. * @param Model $model * @return array the array representation of the errors */ protected function serializeModelErrors($model) { $this->response->setStatusCode(422, 'Data Validation Failed.'); return $this->firstErrors ? $model->getFirstErrors() : $model->getErrors(); }
protected function errorsToPlaceholders(Model $model) { $errors = ArrayHelper::only($model->getErrors(), [], $model->safeAttributes()); $this->template->addMultiPlaceholders($errors); }
/** * Validates one or several models and returns an error message array indexed by the attribute IDs. * This is a helper method that simplifies the way of writing AJAX validation code. * * For example, you may use the following code in a controller action to respond * to an AJAX validation request: * * ```php * $model = new Post; * $model->load($_POST); * if (Rock::$app->request->isAjax) { * Rock::$app->response->format = Response::FORMAT_JSON; * return ActiveForm::validate($model); * } * // ... respond to non-AJAX request ... * ``` * * To validate multiple models, simply pass each model as a parameter to this method, like * the following: * * ```php * ActiveForm::validate($model1, $model2, ...); * ``` * * @param \rock\components\Model $model the model to be validated * @param mixed $attributes list of attributes that should be validated. * If this parameter is empty, it means any attribute listed in the applicable * validation rules should be validated. * * When this method is used to validate multiple models, this parameter will be interpreted * as a model. * * @return array the error message array indexed by the attribute IDs. */ public static function validate($model, $attributes = null) { $result = []; if ($attributes instanceof Model) { // validating multiple models $models = func_get_args(); $attributes = null; } else { $models = [$model]; } /** @var \rock\components\Model $model */ foreach ($models as $model) { $model->validate($attributes); foreach ($model->getErrors() as $attribute => $errors) { $result[ActiveHtml::getInputId($model, $attribute)] = $errors; } } return $result; }