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;
 }
示例#2
0
 /**
  * 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);
 }
示例#4
0
 /**
  * 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;
 }