ICT:D Day problem dd/mm/yyyy
Appearance
Drupal 11.3 Heritage Date Validation Module
This module implements a modern, **Object-Oriented (OOP)** approach to validate text fields for historical dates (1700s–Present) using the `dd/mm/yyyy` format.
Module Configuration
- Machine Name:
heritage_date - Location:
/modules/custom/heritage_date/ - Requirement: Drupal 11.1+ (Uses PHP Attributes for Hooks)
File: heritage_date.info.yml
name: 'Heritage Date Validator'
type: module
description: 'Enforces dd/mm/yyyy format for fields ending in _day.'
package: Custom
core_version_requirement: ^11
File: src/Hook/DateValidationHooks.php
Location: /modules/custom/heritage_date/src/Hook/DateValidationHooks.php
<?php
namespace Drupal\heritage_date\Hook;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Hook\Attribute\Hook;
/**
* Validates text fields for dd/mm/yyyy format.
*/
class DateValidationHooks {
/**
* Implements hook_form_alter().
*/
#[Hook('form_alter')]
public function validateHeritageDate(array &$form, FormStateInterface $form_state, $form_id): void {
// Add the validation handler to all forms.
// The handler will filter by field name suffix.
$form['#validate'][] = [static::class, 'performRegexCheck'];
}
/**
* Scans form for fields ending in '_day' and validates format.
*/
public static function performRegexCheck(array &$form, FormStateInterface $form_state): void {
$values = $form_state->getValues();
foreach ($values as $field_name => $value) {
// Dynamic check for our naming convention
if (str_ends_with($field_name, '_day')) {
$date_string = is_array($value) ? ($value[0]['value'] ?? $value['value'] ?? '') : '';
if (!empty($date_string)) {
// Regex for dd/mm/yyyy
$regex = '/^(0[1-9]|[1-2][0-9]|3)\/(0[1-9]|1[0-2])\/([0-9]{4})$/';
$label = $form[$field_name]['widget']['#title'] ?? $form[$field_name]['#title'] ?? $field_name;
if (!preg_match($regex, $date_string)) {
$form_state->setErrorByName($field_name, t('The @label must be in dd/mm/yyyy format.', ['@label' => $label]));
} else {
// Calendar sanity check (Month, Day, Year)
$parts = explode('/', $date_string);
if (!checkdate((int)$parts[1], (int)$parts[0], (int)$parts[2])) {
$form_state->setErrorByName($field_name, t('The @label contains an invalid calendar date.', ['@label' => $label]));
}
}
}
}
}
}
}
Implementation Commands
To enable and register the new hook system:
- Create the directory structure above.
- Run:
drush en heritage_date - Run:
drush cr(Cache rebuild is mandatory for Hooks to be discovered).