*/ private function rules(): array { return [ 'email' => ['is_email', 'Please enter a valid email address.'], 'phone' => [$this->regexPredicate('\+?[0-9 ()\-]{6,20}'), 'Please enter a valid phone number.'], 'digits' => [$this->regexPredicate('[0-9]+'), 'Please enter digits only.'], ]; } private function regexPredicate(string $pattern): callable { return fn($value): bool => (bool) @preg_match('~^(?:' . $pattern . ')$~u', (string) $value); } /** @return array{0:string,1:callable,2:string}|null */ private function resolveRule(RsvFormElementDefinition $def): ?array { $name = $def->getAttr('validation', ''); if ($name === '') { return null; } if ($name === 'pattern') { $pattern = $def->getAttr('pattern', ''); if ($pattern === '') { return null; } return ['pattern', $this->regexPredicate($pattern), $def->getAttr('pattern_message', '') ?: 'Invalid format.']; } $rules = $this->rules(); if (isset($rules[$name])) { return [$name, $rules[$name][0], $rules[$name][1]]; } return null; } public function draw(RsvFormElementDefinition $def): void { $validation = $def->getAttr('validation', ''); $type = match ($validation) { 'email' => 'email', 'phone' => 'tel', 'digits' => 'number', default => 'text', }; $pattern = $validation === 'pattern' ? $def->getAttr('pattern', '') : ''; ?>