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; }