$value){ if(property_exists($this, $key)){ $this->{$key} = $value; } } } abstract public function rules():array; public function labels(): array{ return []; } public array $errors = []; private function addErrorForRule(string $attribute, string $rule, $params =[]){ $message = $this->errorMessages()[$rule] ?? ''; foreach($params as $key => $value){ $message = str_replace("{{$key}}", $value, $message); } $this->errors[$attribute][] = $message; } public function addError(string $attribute, string $message){ $this->errors[$attribute][] = $message; } public function errorMessages(){ return [ self::RULE_REQUIRED => 'This field is required', self::RULE_EMAIL => 'This field must be valid email address', self::RULE_MIN => 'Min length of this field must be {min}', self::RULE_MAX => 'Max length of this field must be {max}', self::RULE_UNIQUE => 'Email already exists' ]; } public function validate(){ foreach($this->rules() as $attribute => $rules){ $value = $this->{$attribute}; foreach($rules as $rule){ $ruleName = $rule; if(!is_string($ruleName)){ $ruleName = $rule[0]; } if($ruleName === self::RULE_REQUIRED && !$value){ $this->addErrorForRule($attribute, self::RULE_REQUIRED); } if($ruleName === self::RULE_EMAIL && !filter_var($value, FILTER_VALIDATE_EMAIL)){ $this->addErrorForRule($attribute, self::RULE_EMAIL); } if($ruleName === self::RULE_MIN && strlen($value) < $rule['min']){ $this->addErrorForRule($attribute, self::RULE_MIN, $rule); } if($ruleName === self::RULE_MAX && strlen($value) > $rule['max']){ $this->addErrorForRule($attribute, self::RULE_MAX, $rule); } if($ruleName === self::RULE_UNIQUE){ $className = $rule['class']; $uniqueAttr = $rule['attirubute'] ?? $attribute; $tableName = $className::tableName(); $statement = Application::$app->db->prepare(("SELECT * FROM $tableName WHERE $uniqueAttr = :attr")); $statement->bindValue(":attr", $value); $statement->execute(); $record = $statement->fetchObject(); if($record){ $this->addErrorForRule($attribute, SELF::RULE_UNIQUE); } } } } return empty($this->errors); } public function hasError($attribute){ return $this->errors[$attribute] ?? false; } public function getFirstError($attribute){ return $this->errors[$attribute][0] ?? ''; } }