'image/jpeg', 'png' => 'image/png', 'pdf' => 'application/pdf' ]; /** * @var array */ private $params; /** * @var string[] */ private $errors = []; public function __construct(array $params) { $this->params = $params; } /** * Vérifie que les champs soient présents dans le tableau * * @param string[] ...$keys * @return Validator */ public function required(string ...$keys): self { foreach ($keys as $key) { $value = $this->getValue($key); if (is_null($value)) { $this->addError($key, 'required'); } } return $this; } /** * Vérifie que le champ n'est pas vide * * @param string[] ...$keys * @return Validator */ public function notEmpty(string ...$keys): self { foreach ($keys as $key) { $value = $this->getValue($key); if (is_null($value) || empty($value)) { $this->addError($key, 'empty'); } } return $this; } public function length(string $key, ?int $min, ?int $max = null): self { $value = $this->getValue($key); $length = mb_strlen($value); if (!is_null($min) && !is_null($max) && ($length < $min || $length > $max) ) { $this->addError($key, 'betweenLength', [$min, $max]); return $this; } if (!is_null($min) && $length < $min ) { $this->addError($key, 'minLength', [$min]); return $this; } if (!is_null($max) && $length > $max ) { $this->addError($key, 'maxLength', [$max]); } return $this; } /** * Vérifie que l'élément est un slug * * @param string $key * @return Validator */ public function slug(string $key): self { $value = $this->getValue($key); $pattern = '/^[a-z0-9]+(-[a-z0-9]+)*$/'; if (!is_null($value) && !preg_match($pattern, $value)) { $this->addError($key, 'slug'); } return $this; } /** * Vérifie qu'une date correspond au format demandé * * @param string $key * @param string $format * @return Validator */ public function dateTime(string $key, string $format = "Y-m-d H:i:s"): self { $value = $this->getValue($key); $date = \DateTime::createFromFormat($format, $value); $errors = \DateTime::getLastErrors(); if ($errors['error_count'] > 0 || $errors['warning_count'] > 0 || $date === false) { $this->addError($key, 'datetime', [$format]); } return $this; } /** * Vérifie que la clef existe dans la table donnée * * @param string $key * @param string $table * @param \PDO $pdo * @return Validator */ public function exists(string $key, string $table, \PDO $pdo): self { $value = $this->getValue($key); $statement = $pdo->prepare("SELECT id FROM $table WHERE id = ?"); $statement->execute([$value]); if ($statement->fetchColumn() === false) { $this->addError($key, 'exists', [$table]); } return $this; } /** * Vérifie que la clef est unique dans la base de données * * @param string $key * @param string|Table $table * @param \PDO $pdo * @param int|null $exclude * @return Validator */ public function unique(string $key, $table, ?\PDO $pdo = null, ?int $exclude = null): self { if ($table instanceof Table) { $pdo = $table->getPdo(); $table = $table->getTable(); } $value = $this->getValue($key); $query = "SELECT id FROM $table WHERE $key = ?"; $params = [$value]; if ($exclude !== null) { $query .= " AND id != ?"; $params[] = $exclude; } $statement = $pdo->prepare($query); $statement->execute($params); if ($statement->fetchColumn() !== false) { $this->addError($key, 'unique', [$value]); } return $this; } /** * Vérifie si le fichier a bien été uploadé * @param string $key * @return Validator */ public function uploaded(string $key): self { $file = $this->getValue($key); if ($file === null || $file->getError() !== UPLOAD_ERR_OK) { $this->addError($key, 'uploaded'); } return $this; } /** * Vérifie si l'email est valide * @param string $key * @return Validator */ public function email(string $key): self { $value = $this->getValue($key); if (filter_var($value, FILTER_VALIDATE_EMAIL) === false) { $this->addError($key, 'email'); } return $this; } public function confirm(string $key): self { $value = $this->getValue($key); $valueConfirm = $this->getValue($key . '_confirm'); if ($valueConfirm !== $value) { $this->addError($key, 'confirm'); } return $this; } /** * Vérifie le format de fichier * @param string $key * @param array $extensions * @return Validator */ public function extension(string $key, array $extensions): self { /** @var UploadedFileInterface $file */ $file = $this->getValue($key); if ($file !== null && $file->getError() === UPLOAD_ERR_OK) { $type = $file->getClientMediaType(); $extension = mb_strtolower(pathinfo($file->getClientFilename(), PATHINFO_EXTENSION)); $expectedType = self::MIME_TYPES[$extension] ?? null; if (!in_array($extension, $extensions) || $expectedType !== $type) { $this->addError($key, 'filetype', [join(',', $extensions)]); } } return $this; } /** * @return bool */ public function isValid(): bool { return empty($this->errors); } /** * Récupère les erreurs * @return ValidationError[] */ public function getErrors(): array { return $this->errors; } /** * Ajoute une erreur * * @param string $key * @param string $rule * @param array $attributes */ private function addError(string $key, string $rule, array $attributes = []): void { $this->errors[$key] = new ValidationError($key, $rule, $attributes); } private function getValue(string $key) { if (array_key_exists($key, $this->params)) { return $this->params[$key]; } return null; } }