name = $name; } /** * Validates this field against its internal and added conditions. * * Returns true if all conditions are met, or false if there are errors. * If the result is false, a list of errors can be retrieved using the getErrors() method. * @see getErrors * * @return bool */ public function validate(): bool { // Prepare output variables $this->errors = []; $this->validated = true; $this->valid = true; // Check if empty or null if (empty($this->value)) { // If the value is empty and not optional, turn it into an error if (!$this->optional) { $this->valid = false; if (!is_null($this->emptyErrorString)) $this->errors[] = $this->emptyErrorString; else $this->errors[] = $this->getLabel() . " may not be empty."; return false; } // If the value is empty but also optional, that's perfectly fine. Immediately accept without any further tests. return true; } // Check validateField if (!$this->validateField()) $this->valid = false; // Check for conditions foreach ($this->conditions as $condition) if (!call_user_func($condition, $this)) $this->valid = false; return $this->valid; } /** * Whether the field has been validated. * * @see validate * @return bool */ public function isValidated(): bool { return $this->validated; } /** * Whether the field has met all conditions during validation * * @return bool */ public function isValid(): bool { return $this->valid; } /** * Change the valid status of the field to false, if so required by post-checks. * * @return void */ public function invalidate(): void { $this->valid = false; } /** * Returns the name of the field, as was added with the construction of the field. * * @return string */ public function getName(): string { return $this->name; } /** * Returns the currently set value of the field. * * @return mixed */ public function getValue(): mixed { return $this->value; } /** * Returns the unique identifier of the field. * * If an identifier has been set, it shall return 'formName_fieldIdentifier' * If no identifier has been set, it shall return 'formName_fieldName' * * @return string */ public function getId(): string { if (is_null($this->identifier)) return $this->formName . "_" . $this->name; return $this->formName . "_" . $this->identifier; } /** * Returns the label of this field, which is the most human-readable. * * If a label has been set, returns that label. * If no label has been set, returns ucfirst(fieldName). * * @return string */ public function getLabel(): string { return is_null($this->label) ? ucfirst($this->name) : $this->label; } /** * Returns the note of this field. * * Notes are there for the developer to categorize fields, if this is required. * * @return string|null */ public function getNote(): ?string { return $this->note; } /** * Returns an array of strings with all errors found during validation. * * @return string[] */ public function getErrors(): array { return $this->errors; } /** * Set the current value of this field, which it may be validated against. * ALWAYS VERIFY AGAINST XSS ATTACKS!!!!!!!!!! * * If field is locked the value will not be updated. * @see lock * * @param mixed $value * @return $this */ public function setValue(mixed $value): static { if (!$this->lock) $this->value = $value; return $this; } /** * Sets the identifier of the field. * * @param string $identifier * @return $this */ public function setId(string $identifier): static { $this->identifier = $identifier; return $this; } /** * Sets the label of the field. * * @param string $label * @return $this */ public function setLabel(string $label): static { $this->label = $label; return $this; } /** * Sets the note of the field. * * @param string $note * @return $this */ public function setNote(string $note): static { $this->note = $note; return $this; } /** * When enabled, locks the field, so it may not be edited anymore. * * @param bool $lock * @return $this */ public function lock(bool $lock = true): static { $this->lock = $lock; return $this; } /** * When enabled, marks the field as optional, so that it may be left empty during validation. * * @param bool $opt * @return $this */ public function optional(bool $opt = true): static { $this->optional = $opt; return $this; } /** * Adds a manual condition to the field that it will be validated against. * * @param callable $condition * @return $this */ public function condition(callable $condition): static { $this->conditions[] = $condition; return $this; } /** * Set the string to be displayed when a value is not set and isn't optional. * * @param string $errorString * @return $this */ public function emptyErrorString(string $errorString): static { $this->emptyErrorString = $errorString; return $this; } /** * Add an error to be displayed on this field. * * @param string $errorString * @return $this */ public function addError(string $errorString): static { $this->errors[] = $errorString; return $this; } /** * Adds the CSS classnames to be printed inside the element. * * @param array $classNames * @return $this */ public function class(array $classNames): static { foreach ($classNames as $className) $this->classNames[] = $className; return $this; } /** * Add one CSS classname to be printed inside the element * * @param string $class * @return $this */ public function addClass(string $class): static { $this->classNames[] = $class; return $this; } /** * Sets the CSS classnames to be printed inside the element * * @param array $classNames * @return $this */ public function setClasses(array $classNames): static { $this->classNames = $classNames; return $this; } /** * @internal */ public function setFormName(string $formName): void { $this->formName = $formName; } /** * Run a validation test against internal conditions. * * Gets called by validate() method * @see validate * * @return bool */ protected abstract function validateField(): bool; /** * Generates a html string that will be added to the form. * * @return string */ public abstract function generateHtml(): string; public function __toString() { return $this->generateHtml(); } }