Add schema constraints and #config_target to make Date AP Style configuration fully validatable

Created on 23 August 2025, 18 days ago

Problem/Motivation

Date AP Style’s settings schema is present but not fully constrained, which allows invalid values to be saved/imported and prevents 100% config validation.
Drupal 10.3 introduced configuration validation constraints and #config_target so modules can strictly validate settings:
#3376195 Choice constraint for configuration schema β†’ ,
#3373502 Using validation constraints via #config_target β†’ .

Steps to reproduce

  1. On a site using the module, set (or import) a setting to an unsupported value (e.g., a non‑IANA timezone or an arbitrary range separator).
  2. Save/import succeeds; no validation error is raised.

Proposed resolution

  • Add strict constraints to config/schema/date_ap_style.schema.yml:
    • separator: Choice with explicit options (endash, to).
    • timezone: Choice with callback to \Drupal\Core\Datetime\TimeZoneFormHelper::getOptionsList (as per change record).
    • Ensure schema defaults match defaultConfiguration().
  • Refactor settings form to use #config_target for each element so schema constraints are enforced automatically on submit.
  • Add tests:
    • Kernel: invalid values are rejected during config save/import; valid values round‑trip cleanly.
    • Functional: UI shows inline errors when submitting invalid inputs.
  • If necessary, add a post_update to normalize legacy/invalid stored values to valid defaults.
  • Set/confirm minimum core version to 10.3+ (required for constraints + #config_target workflow).

Remaining tasks

  • [ ] Add/adjust constraints in date_ap_style.schema.yml (separator Choice, timezone Choice callback).
  • [ ] Align schema defaults with defaultConfiguration().
  • [ ] Update settings form elements to use #config_target.
  • [ ] Write Kernel tests for invalid/valid config.
  • [ ] Write Functional tests for form validation.
  • [ ] (If needed) Implement hook_post_update() to normalize existing config.
  • [ ] Update README/CHANGELOG to document stricter validation and core 10.3+.

User interface changes

No new UI. Invalid inputs now display standard inline error messages on the settings form.

API changes

None.

Data model changes

None.

Illustrative schema snippet

date_ap_style.settings:
  type: mapping
  label: 'Date AP Style Settings'
  mapping:
    separator:
      type: string
      label: 'Date range separator'
      constraints:
        Choice:
          choices:
            - endash
            - to
    timezone:
      type: string
      label: 'Timezone'
      constraints:
        Choice:
          callback: 'DateTimeZone::listIdentifiers'

Release notes (when merged)

  • Configuration is now strictly validated using schema constraints and #config_target.
  • Sites on Drupal 10.0–10.2 must upgrade core to β‰₯10.3 before updating this module.
✨ Feature request
Status

Active

Version

2.0

Component

Code

Created by

πŸ‡ΊπŸ‡ΈUnited States trackleft2 Tucson, AZ πŸ‡ΊπŸ‡Έ

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @trackleft2
  • πŸ‡ΊπŸ‡ΈUnited States trackleft2 Tucson, AZ πŸ‡ΊπŸ‡Έ
  • πŸ‡ΊπŸ‡ΈUnited States trackleft2 Tucson, AZ πŸ‡ΊπŸ‡Έ
  • πŸ‡ΊπŸ‡ΈUnited States trackleft2 Tucson, AZ πŸ‡ΊπŸ‡Έ
  • πŸ‡ΊπŸ‡ΈUnited States trackleft2 Tucson, AZ πŸ‡ΊπŸ‡Έ

    On initial module install, this is what I see when I run the config_inspector module drush config:inspect command

     git:(main) lando drush config:inspect date_ap_style.dateapstylesettings --detail
    ➜  πŸ€– Analyzing…
    
     Legend for Data: 
      βœ…β“  β†’ Correct primitive type, detailed validation impossible.
      βœ…βœ…  β†’ Correct primitive type, passed all validation constraints.
     ---------------------------------------------------------- ---------------- ------------- ------ 
      Key                                                        Status           Validatable   Data  
     ---------------------------------------------------------- ---------------- ------------- ------ 
      date_ap_style.dateapstylesettings:_core                    missing schema                       
      date_ap_style.dateapstylesettings:date_ap_style_settings   missing schema                       
     ---------------------------------------------------------- ---------------- ------------- ------ 
    

    And on an entity view display using the timestamp_ap_style formatter.

     lando drush config:inspect core.entity_view_display.node.az_news.az_row --detail
    ➜  πŸ€– Analyzing…
    
     Legend for Data: 
      βœ…β“  β†’ Correct primitive type, detailed validation impossible.
      βœ…βœ…  β†’ Correct primitive type, passed all validation constraints.
     --------------------------------------------------------------------------------------------------------------- ---------------- ------------- ------ 
      Key                                                                                                             Status           Validatable   Data  
     --------------------------------------------------------------------------------------------------------------- ---------------- ------------- ------ 
      core.entity_view_display.node.az_news.az_row:content.field_az_published.settings.always_display_year            missing schema                       
      core.entity_view_display.node.az_news.az_row:content.field_az_published.settings.use_today                      missing schema                       
      core.entity_view_display.node.az_news.az_row:content.field_az_published.settings.display_day                    missing schema                       
      core.entity_view_display.node.az_news.az_row:content.field_az_published.settings.use_all_day                    missing schema                       
      core.entity_view_display.node.az_news.az_row:content.field_az_published.settings.timezone                       missing schema                       
      core.entity_view_display.node.az_news.az_row:content.field_az_published.settings.cap_today                      missing schema                       
      core.entity_view_display.node.az_news.az_row:content.field_az_published.settings.display_time                   missing schema                       
      core.entity_view_display.node.az_news.az_row:content.field_az_published.settings.time_before_date               missing schema                       
      core.entity_view_display.node.az_news.az_row:content.field_az_published.settings.display_noon_and_midnight      missing schema                       
      core.entity_view_display.node.az_news.az_row:content.field_az_published.settings.capitalize_noon_and_midnight   missing schema                       
      core.entity_view_display.node.az_news.az_row:content.field_az_published.settings.hide_date                      missing schema                       
      core.entity_view_display.node.az_news.az_row:content.field_az_published.settings.month_only                     missing schema                       
     --------------------------------------------------------------------------------------------------------------- ---------------- ------------- ------ 
    

    And on the daterange_ap_style formatter.

    lando drush config:inspect core.entity_view_display.node.az_event.az_card_alternate --detail
    ➜  πŸ€– Analyzing…
    
     Legend for Data: 
      βœ…β“  β†’ Correct primitive type, detailed validation impossible.
      βœ…βœ…  β†’ Correct primitive type, passed all validation constraints.
     ---------------------------------------------------------------------------------------------------------------------------- ---------------- ------------- ------ 
      Key                                                                                                                          Status           Validatable   Data  
     ---------------------------------------------------------------------------------------------------------------------------- ---------------- ------------- ------ 
      core.entity_view_display.node.az_event.az_card_alternate:content.field_az_event_date.settings.always_display_year            missing schema                       
      core.entity_view_display.node.az_event.az_card_alternate:content.field_az_event_date.settings.use_today                      missing schema                       
      core.entity_view_display.node.az_event.az_card_alternate:content.field_az_event_date.settings.cap_today                      missing schema                       
      core.entity_view_display.node.az_event.az_card_alternate:content.field_az_event_date.settings.display_time                   missing schema                       
      core.entity_view_display.node.az_event.az_card_alternate:content.field_az_event_date.settings.time_before_date               missing schema                       
      core.entity_view_display.node.az_event.az_card_alternate:content.field_az_event_date.settings.display_noon_and_midnight      missing schema                       
      core.entity_view_display.node.az_event.az_card_alternate:content.field_az_event_date.settings.use_all_day                    missing schema                       
      core.entity_view_display.node.az_event.az_card_alternate:content.field_az_event_date.settings.separator                      missing schema                       
      core.entity_view_display.node.az_event.az_card_alternate:content.field_az_event_date.settings.timezone                       missing schema                       
      core.entity_view_display.node.az_event.az_card_alternate:content.field_az_event_date.settings.display_day                    missing schema                       
      core.entity_view_display.node.az_event.az_card_alternate:content.field_az_event_date.settings.month_only                     missing schema                       
      core.entity_view_display.node.az_event.az_card_alternate:content.field_az_event_date.settings.hide_date                      missing schema                       
      core.entity_view_display.node.az_event.az_card_alternate:content.field_az_event_date.settings.capitalize_noon_and_midnight   missing schema                       
     ---------------------------------------------------------------------------------------------------------------------------- ---------------- ------------- ------ 
    

    Then when I run the database updates I see:

    lando drush updatedb:status --format=table
     --------------- ---------------------------- ------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
      Module          Update ID                    Type          Description                                                                                                                                                                    
     --------------- ---------------------------- ------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
      date_ap_style   migrate_and_cleanup_config   post-update   Migrate configuration and fix data types for existing installations.   This comprehensive post-update function handles:  - Migration from old config name                      
                                                                 (date_ap_style.dateapstylesettings)    to new (date_ap_style.settings)  - Cleanup of invalid configuration keys  - Conversion of stringinteger values to proper boolean types  
                                                                 in main config  - Conversion of stringinteger values to proper boolean types in    entity view display configs  - Handles both fresh installations and existing sites.         
     --------------- ---------------------------- ------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
    
    lando drush updatedb -y                   
     --------------- ----------- ------------- ------------------------------------------- 
      Module          Update ID   Type          Description                                
     --------------- ----------- ------------- ------------------------------------------- 
      date_ap_style   mi          post-update   Migrate configuration and fix data types   
                      gr                        for existing installations.   This         
                      at                        comprehensive post-update function         
                      e_                        handles:  - Migration from old config      
                      an                        name (date_ap_style.dateapstylesettings)   
                      d_                          to new (date_ap_style.settings)  -       
                      cl                        Cleanup of invalid configuration keys  -   
                      ea                        Conversion of stringinteger values to      
                      nu                        proper boolean types in main config  -     
                      p_                        Conversion of stringinteger values to      
                      co                        proper boolean types in    entity view     
                      nf                        display configs  - Handles both fresh      
                      ig                        installations and existing sites.          
     --------------- ----------- ------------- ------------------------------------------- 
    
    
     // Do you wish to run the specified pending updates?: yes.                                                             
    
    >  [notice] Update started: date_ap_style_post_update_migrate_and_cleanup_config
    >  [notice] Migrated configuration from date_ap_style.dateapstylesettings to date_ap_style.settings. Cleaned up main configuration and fixed data types. Fixed data types in 12 entity view display configurations.
    >  [notice] Update completed: date_ap_style_post_update_migrate_and_cleanup_config
     [success] Finished performing updates.
    
     lando drush config:inspect date_ap_style.dateapstylesettings --detail                       
    ➜  πŸ€– Analyzing…
    
     [warning] Undefined variable $all_property_paths InspectorCommands.php:259
     [warning] foreach() argument must be of type array|object, null given InspectorCommands.php:259
     Legend for Data: 
      βœ…β“  β†’ Correct primitive type, detailed validation impossible.
      βœ…βœ…  β†’ Correct primitive type, passed all validation constraints.
     ----------------------------------- ----------- ------------- ------ 
      Key                                 Status      Validatable   Data  
     ----------------------------------- ----------- ------------- ------ 
      date_ap_style.dateapstylesettings   No schema                       
     ----------------------------------- ----------- ------------- ------ 
    
    lando drush config:inspect date_ap_style.settings --detail
    ➜  πŸ€– Analyzing…
    
     Legend for Data: 
      βœ…β“  β†’ Correct primitive type, detailed validation impossible.
      βœ…βœ…  β†’ Correct primitive type, passed all validation constraints.
     ------------------------------------------------------ --------- ------------- ------ 
      Key                                                    Status    Validatable   Data  
     ------------------------------------------------------ --------- ------------- ------ 
      date_ap_style.settings                                 Correct   100%          βœ…βœ…  
       date_ap_style.settings:                               Correct   Validatable   βœ…βœ…  
       date_ap_style.settings:always_display_year            Correct   Validatable   βœ…βœ…  
       date_ap_style.settings:cap_today                      Correct   Validatable   βœ…βœ…  
       date_ap_style.settings:capitalize_noon_and_midnight   Correct   Validatable   βœ…βœ…  
       date_ap_style.settings:display_day                    Correct   Validatable   βœ…βœ…  
       date_ap_style.settings:display_noon_and_midnight      Correct   Validatable   βœ…βœ…  
       date_ap_style.settings:display_time                   Correct   Validatable   βœ…βœ…  
       date_ap_style.settings:hide_date                      Correct   Validatable   βœ…βœ…  
       date_ap_style.settings:month_only                     Correct   Validatable   βœ…βœ…  
       date_ap_style.settings:separator                      Correct   Validatable   βœ…βœ…  
       date_ap_style.settings:time_before_date               Correct   Validatable   βœ…βœ…  
       date_ap_style.settings:timezone                       Correct   Validatable   βœ…βœ…  
       date_ap_style.settings:use_all_day                    Correct   Validatable   βœ…βœ…  
       date_ap_style.settings:use_today                      Correct   Validatable   βœ…βœ…  
     ------------------------------------------------------ --------- ------------- ------ 
    
     lando drush config:inspect core.entity_view_display.node.az_event.az_card_alternate --detail
    ➜  πŸ€– Analyzing…
    
     Legend for Data: 
      βœ…β“  β†’ Correct primitive type, detailed validation impossible.
      βœ…βœ…  β†’ Correct primitive type, passed all validation constraints.
     ------------------------------------------------------------------------------------------------------------------------------------------------------- --------- ------------- ------ 
      Key                                                                                                                                                     Status    Validatable   Data  
     ------------------------------------------------------------------------------------------------------------------------------------------------------- --------- ------------- ------ 
      core.entity_view_display.node.az_event.az_card_alternate                                                                                                Correct   52%           βœ…β“  
       core.entity_view_display.node.az_event.az_card_alternate:                                                                                              Correct   Validatable   βœ…βœ…  
       core.entity_view_display.node.az_event.az_card_alternate:_core                                                                                         Correct   Validatable   βœ…βœ…  
       core.entity_view_display.node.az_event.az_card_alternate:_core.default_config_hash                                                                     Correct   Validatable   βœ…βœ…  
       core.entity_view_display.node.az_event.az_card_alternate:bundle                                                                                        Correct   Validatable   βœ…βœ…  
       core.entity_view_display.node.az_event.az_card_alternate:content                                                                                       Correct   NOT           βœ…β“  
       core.entity_view_display.node.az_event.az_card_alternate:content.field_az_event_date                                                                   Correct   Validatable   βœ…βœ…  
       core.entity_view_display.node.az_event.az_card_alternate:content.field_az_event_date.label                                                             Correct   NOT           βœ…β“  
       core.entity_view_display.node.az_event.az_card_alternate:content.field_az_event_date.region                                                            Correct   NOT           βœ…β“  
       core.entity_view_display.node.az_event.az_card_alternate:content.field_az_event_date.settings                                                          Correct   Validatable   βœ…βœ…  
       core.entity_view_display.node.az_event.az_card_alternate:content.field_az_event_date.settings.always_display_year                                      Correct   Validatable   βœ…βœ…  
       core.entity_view_display.node.az_event.az_card_alternate:content.field_az_event_date.settings.cap_today                                                Correct   Validatable   βœ…βœ…  
       core.entity_view_display.node.az_event.az_card_alternate:content.field_az_event_date.settings.capitalize_noon_and_midnight                             Correct   Validatable   βœ…βœ…  
       core.entity_view_display.node.az_event.az_card_alternate:content.field_az_event_date.settings.display_day                                              Correct   Validatable   βœ…βœ…  
       core.entity_view_display.node.az_event.az_card_alternate:content.field_az_event_date.settings.display_noon_and_midnight                                Correct   Validatable   βœ…βœ…  
       core.entity_view_display.node.az_event.az_card_alternate:content.field_az_event_date.settings.display_time                                             Correct   Validatable   βœ…βœ…  
       core.entity_view_display.node.az_event.az_card_alternate:content.field_az_event_date.settings.hide_date                                                Correct   Validatable   βœ…βœ…  
       core.entity_view_display.node.az_event.az_card_alternate:content.field_az_event_date.settings.month_only                                               Correct   Validatable   βœ…βœ…  
       core.entity_view_display.node.az_event.az_card_alternate:content.field_az_event_date.settings.separator                                                Correct   Validatable   βœ…βœ…  
       core.entity_view_display.node.az_event.az_card_alternate:content.field_az_event_date.settings.time_before_date                                         Correct   Validatable   βœ…βœ…  
       core.entity_view_display.node.az_event.az_card_alternate:content.field_az_event_date.settings.timezone                                                 Correct   Validatable   βœ…βœ…  
       core.entity_view_display.node.az_event.az_card_alternate:content.field_az_event_date.settings.use_all_day                                              Correct   Validatable   βœ…βœ…  
       core.entity_view_display.node.az_event.az_card_alternate:content.field_az_event_date.settings.use_today                                                Correct   Validatable   βœ…βœ…  
    
    
     lando drush config:inspect core.entity_view_display.node.az_news.az_row --detail            
    ➜  πŸ€– Analyzing…
    
     Legend for Data: 
      βœ…β“  β†’ Correct primitive type, detailed validation impossible.
      βœ…βœ…  β†’ Correct primitive type, passed all validation constraints.
     ---------------------------------------------------------------------------------------------------------------------------------------- --------- ------------- ------ 
      Key                                                                                                                                      Status    Validatable   Data  
     ---------------------------------------------------------------------------------------------------------------------------------------- --------- ------------- ------ 
      core.entity_view_display.node.az_news.az_row                                                                                             Correct   50%           βœ…β“  
       core.entity_view_display.node.az_news.az_row:                                                                                           Correct   Validatable   βœ…βœ…  
       core.entity_view_display.node.az_news.az_row:_core                                                                                      Correct   Validatable   βœ…βœ…  
       core.entity_view_display.node.az_news.az_row:_core.default_config_hash                                                                  Correct   Validatable   βœ…βœ…  
       core.entity_view_display.node.az_news.az_row:bundle                                                                                     Correct   Validatable   βœ…βœ…  
       core.entity_view_display.node.az_news.az_row:content                                                                                    Correct   NOT           βœ…β“  
       core.entity_view_display.node.az_news.az_row:content.field_az_media_image                                                               Correct   Validatable   βœ…βœ…  
       core.entity_view_display.node.az_news.az_row:content.field_az_media_image.label                                                         Correct   NOT           βœ…β“  
       core.entity_view_display.node.az_news.az_row:content.field_az_media_image.region                                                        Correct   NOT           βœ…β“  
       core.entity_view_display.node.az_news.az_row:content.field_az_media_image.settings                                                      Correct   Validatable   βœ…βœ…  
       core.entity_view_display.node.az_news.az_row:content.field_az_media_image.settings.image_link                                           Correct   NOT           βœ…β“  
       core.entity_view_display.node.az_news.az_row:content.field_az_media_image.settings.image_loading                                        Correct   Validatable   βœ…βœ…  
       core.entity_view_display.node.az_news.az_row:content.field_az_media_image.settings.image_loading.attribute                              Correct   NOT           βœ…β“  
       core.entity_view_display.node.az_news.az_row:content.field_az_media_image.settings.image_style                                          Correct   NOT           βœ…β“  
       core.entity_view_display.node.az_news.az_row:content.field_az_media_image.third_party_settings                                          Correct   NOT           βœ…β“  
       core.entity_view_display.node.az_news.az_row:content.field_az_media_image.type                                                          Correct   Validatable   βœ…βœ…  
       core.entity_view_display.node.az_news.az_row:content.field_az_media_image.weight                                                        Correct   Validatable   βœ…βœ…  
       core.entity_view_display.node.az_news.az_row:content.field_az_published                                                                 Correct   Validatable   βœ…βœ…  
       core.entity_view_display.node.az_news.az_row:content.field_az_published.label                                                           Correct   NOT           βœ…β“  
       core.entity_view_display.node.az_news.az_row:content.field_az_published.region                                                          Correct   NOT           βœ…β“  
       core.entity_view_display.node.az_news.az_row:content.field_az_published.settings                                                        Correct   Validatable   βœ…βœ…  
       core.entity_view_display.node.az_news.az_row:content.field_az_published.settings.always_display_year                                    Correct   Validatable   βœ…βœ…  
       core.entity_view_display.node.az_news.az_row:content.field_az_published.settings.cap_today                                              Correct   Validatable   βœ…βœ…  
       core.entity_view_display.node.az_news.az_row:content.field_az_published.settings.capitalize_noon_and_midnight                           Correct   Validatable   βœ…βœ…  
       core.entity_view_display.node.az_news.az_row:content.field_az_published.settings.display_day                                            Correct   Validatable   βœ…βœ…  
       core.entity_view_display.node.az_news.az_row:content.field_az_published.settings.display_noon_and_midnight                              Correct   Validatable   βœ…βœ…  
       core.entity_view_display.node.az_news.az_row:content.field_az_published.settings.display_time                                           Correct   Validatable   βœ…βœ…  
       core.entity_view_display.node.az_news.az_row:content.field_az_published.settings.hide_date                                              Correct   Validatable   βœ…βœ…  
       core.entity_view_display.node.az_news.az_row:content.field_az_published.settings.month_only                                             Correct   Validatable   βœ…βœ…  
       core.entity_view_display.node.az_news.az_row:content.field_az_published.settings.time_before_date                                       Correct   Validatable   βœ…βœ…  
       core.entity_view_display.node.az_news.az_row:content.field_az_published.settings.timezone                                               Correct   Validatable   βœ…βœ…  
       core.entity_view_display.node.az_news.az_row:content.field_az_published.settings.use_all_day                                            Correct   Validatable   βœ…βœ…  
       core.entity_view_display.node.az_news.az_row:content.field_az_published.settings.use_today                                              Correct   Validatable   βœ…βœ…  
    
  • πŸ‡ΊπŸ‡ΈUnited States trackleft2 Tucson, AZ πŸ‡ΊπŸ‡Έ

    There are still some undone tasks.

  • πŸ‡ΊπŸ‡ΈUnited States trackleft2 Tucson, AZ πŸ‡ΊπŸ‡Έ
  • πŸ‡ΊπŸ‡ΈUnited States trackleft2 Tucson, AZ πŸ‡ΊπŸ‡Έ
  • Pipeline finished with Failed
    13 days ago
    #583736
  • πŸ‡ΊπŸ‡ΈUnited States trackleft2 Tucson, AZ πŸ‡ΊπŸ‡Έ
  • πŸ‡ΊπŸ‡ΈUnited States trackleft2 Tucson, AZ πŸ‡ΊπŸ‡Έ
  • πŸ‡ΊπŸ‡ΈUnited States trackleft2 Tucson, AZ πŸ‡ΊπŸ‡Έ
  • πŸ‡ΊπŸ‡ΈUnited States trackleft2 Tucson, AZ πŸ‡ΊπŸ‡Έ
  • πŸ‡ΊπŸ‡ΈUnited States trackleft2 Tucson, AZ πŸ‡ΊπŸ‡Έ
Production build 0.71.5 2024