diff --git a/README.md b/README.md index 3dc7987..9a3cf06 100644 --- a/README.md +++ b/README.md @@ -22,14 +22,16 @@ greatly appreciated. ## Content Types Below is a list of the (at least partially) implemented content types with -their fields. *Emphasized fields* were originally planned but proved infeasible -given the structure of Drupal's RDF module and the Islandora JSON-LD module. +their fields. The fields with "EDTF L1" accept and display dates corresponding +to the Library of Congress [2012 Extended Date/Time Format Specification](http://www.loc.gov/standards/datetime/pre-submission.html) +_Level 1_. [EDTF was incorporated in ISO 8601-2019 with some modifications](http://www.loc.gov/standards/datetime/edtf.html) +which will be supported in a future update. - Corporate Body - Preferred Name (Title) - Alternate Name - - Founding Date (EDTF v.1) - - Dissolution Date (EDTF v.1) + - Founding Date (EDTF L1) + - Dissolution Date (EDTF L1) - Parent Organization - Authorities - Description @@ -49,14 +51,14 @@ given the structure of Drupal's RDF module and the Islandora JSON-LD module. - Display Label (Title) - Authorities - Relation - - Date Begin (EDTF v.1) - - Date End (EDTF v.1) + - Date Begin (EDTF L1) + - Date End (EDTF L1) - Person - Title/Display Name - Alternate Name - Preferred Name - - Birth Date (EDTF v.1) - - Death Date (EDTF v.1) + - Birth Date (EDTF L1) + - Death Date (EDTF L1) - Relation - Authorities - Description diff --git a/controlled_access_terms.module b/controlled_access_terms.module index c31673a..a5fb060 100644 --- a/controlled_access_terms.module +++ b/controlled_access_terms.module @@ -7,6 +7,9 @@ use Drupal\jsonld\Normalizer\NormalizerBase; use Drupal\Core\Entity\EntityInterface; +use Drupal\controlled_access_terms\EDTFConverter; +use Drupal\field\Entity\FieldStorageConfig; +use Drupal\field\Entity\FieldConfig; /** * Implements hook_rdf_namespaces(). @@ -15,6 +18,7 @@ function controlled_access_terms_rdf_namespaces() { return [ 'wgs84_pos' => 'http://www.w3.org/2003/01/geo/wgs84_pos#', 'org' => 'https://www.w3.org/TR/vocab-org/#org:', + 'xs' => 'http://www.w3.org/2001/XMLSchema#', ]; } @@ -24,17 +28,113 @@ function controlled_access_terms_rdf_namespaces() { function controlled_access_terms_jsonld_alter_normalized_array(EntityInterface $entity, array &$normalized, array $context) { if (isset($normalized['@graph']) && is_array($normalized['@graph'])) { foreach ($entity->getFieldDefinitions() as $field => $field_definition) { - if (($field_definition->getType() == 'typed_relation') && (!empty($entity->get($field)->getValue()))) { - foreach ($entity->get($field)->getValue() as $value) { - $predicate = NormalizerBase::escapePrefix($value['rel_type'], $context['namespaces']); - $referenced_entity = \Drupal::entityTypeManager()->getStorage($field_definition->getSetting('target_type'))->load($value['target_id']); - // We are assuming the first graph is the one corresponding - // to the node/taxonomy_term we are modifying. - $normalized['@graph'][0][$predicate][] = [ - '@id' => $referenced_entity->toUrl('canonical', ['absolute' => TRUE])->setRouteParameter('_format', 'jsonld')->toString(), - ]; + if (!empty($entity->get($field)->getValue())) { + if ($field_definition->getType() == 'typed_relation') { + foreach ($entity->get($field)->getValue() as $value) { + $predicate = NormalizerBase::escapePrefix($value['rel_type'], $context['namespaces']); + $referenced_entity = \Drupal::entityTypeManager()->getStorage($field_definition->getSetting('target_type'))->load($value['target_id']); + // We are assuming the first graph is the one corresponding + // to the node/taxonomy_term we are modifying. + $normalized['@graph'][0][$predicate][] = [ + '@id' => $referenced_entity->toUrl('canonical', ['absolute' => TRUE])->setRouteParameter('_format', 'jsonld')->toString(), + ]; + } } + elseif ($field_definition->getType() == 'edtf') { + // Get the predicate to look in. + foreach ($context['current_entity_rdf_mapping']->get('fieldMappings')[$field]['properties'] as $predicate) { + // Find the predicate value that needs updating. + $predicate_normalized = NormalizerBase::escapePrefix($predicate, $context['namespaces']); + foreach ($normalized['@graph'][0][$predicate_normalized] as $index => $value) { + // Clean the date of ranges, uncertainty, and approximations. + // Have to remap the array from '@value' to 'value'. + $normalized_date = EDTFConverter::dateIso8601Value(['value' => $value['@value']]); + + // Determine which type to use. + $date_type = NormalizerBase::escapePrefix('xs:date', $context['namespaces']); + switch (count(explode('-', $normalized_date))) { + case 1: + $date_type = NormalizerBase::escapePrefix('xs:gYear', $context['namespaces']); + break; + + case 2: + $date_type = NormalizerBase::escapePrefix('xs:gYearMonth', $context['namespaces']); + break; + } + $normalized['@graph'][0][$predicate_normalized][] = [ + '@value' => $normalized_date, + '@type' => $date_type, + ]; + } + } + } + } + } + } +} + +/** + * Change fields using the EDTF Widget to the new EDTF Field Type. + */ +function controlled_access_terms_update_8002() { + // Ensure the new EDTF plugins can be found. + \Drupal::service('plugin.manager.field.field_type')->clearCachedDefinitions(); + + // Find all the fields using the text_edtf widget via form configs. + $config_factory = \Drupal::configFactory(); + foreach ($config_factory->listAll('core.entity_form_display.') as $entity_form_display_config_name) { + $entity_form_display = $config_factory->getEditable($entity_form_display_config_name); + $fields = $entity_form_display->get('content'); + foreach ($fields as $field_name => $field_settings) { + if (isset($field_settings['type']) && $field_settings['type'] === 'text_edtf') { + + // Update this form setting. + $entity_form_display->set("content.$field_name.type", 'edtf_default'); + + // Update the field setting. + if (!$fields = \Drupal::entityManager()->getStorage('field_config')->loadByProperties(['field_name' => $field_name])) { + continue; + } + else { + foreach ($fields as $field) { + $new_field = $field->toArray(); + $new_field['field_type'] = 'edtf'; + $new_field = FieldConfig::create($new_field); + $new_field->original = $new_field; + $new_field->enforceIsNew(FALSE); + $new_field->save(); + } + } + + // Update the field storage setting. + if (!$field_storage_configs = \Drupal::entityManager()->getStorage('field_storage_config')->loadByProperties(['field_name' => $field_name])) { + continue; + } + else { + foreach ($field_storage_configs as $field_storage) { + $new_field_storage = $field_storage->toArray(); + $new_field_storage['type'] = 'edtf'; + $new_field_storage = FieldStorageConfig::create($new_field_storage); + $new_field_storage->original = $new_field_storage; + $new_field_storage->enforceIsNew(FALSE); + $new_field_storage->save(); + } + } + } + } + $entity_form_display->save(TRUE); + } + + // Find display configs. + foreach ($config_factory->listAll('core.entity_view_display.') as $entity_view_display_config_name) { + $entity_view_display = $config_factory->getEditable($entity_view_display_config_name); + $fields = $entity_view_display->get('content'); + foreach ($fields as $field_name => $field_settings) { + if (isset($field_settings['type']) && ($field_settings['type'] === 'text_edtf_human' || $field_settings['type'] === 'text_edtf_iso8601')) { + // Update this view setting. + $entity_view_display->set("content.$field_name.type", 'edtf_default'); } } + $entity_view_display->save(TRUE); } } diff --git a/modules/controlled_access_terms_default_configuration/config/install/core.entity_form_display.taxonomy_term.corporate_body.default.yml b/modules/controlled_access_terms_default_configuration/config/install/core.entity_form_display.taxonomy_term.corporate_body.default.yml index cf81ea8..f9f59b4 100644 --- a/modules/controlled_access_terms_default_configuration/config/install/core.entity_form_display.taxonomy_term.corporate_body.default.yml +++ b/modules/controlled_access_terms_default_configuration/config/install/core.entity_form_display.taxonomy_term.corporate_body.default.yml @@ -40,7 +40,7 @@ content: strict_dates: false intervals: false third_party_settings: { } - type: text_edtf + type: edtf_default region: content field_cat_date_end: weight: 5 @@ -48,7 +48,7 @@ content: strict_dates: false intervals: false third_party_settings: { } - type: text_edtf + type: edtf_default region: content field_corp_alt_name: weight: 6 diff --git a/modules/controlled_access_terms_default_configuration/config/install/core.entity_form_display.taxonomy_term.family.default.yml b/modules/controlled_access_terms_default_configuration/config/install/core.entity_form_display.taxonomy_term.family.default.yml index caead34..c5ff0a9 100644 --- a/modules/controlled_access_terms_default_configuration/config/install/core.entity_form_display.taxonomy_term.family.default.yml +++ b/modules/controlled_access_terms_default_configuration/config/install/core.entity_form_display.taxonomy_term.family.default.yml @@ -38,7 +38,7 @@ content: strict_dates: false intervals: false third_party_settings: { } - type: text_edtf + type: edtf_default region: content field_cat_date_end: weight: 9 @@ -46,7 +46,7 @@ content: strict_dates: false intervals: false third_party_settings: { } - type: text_edtf + type: edtf_default region: content field_relationships: weight: 123 diff --git a/modules/controlled_access_terms_default_configuration/config/install/core.entity_form_display.taxonomy_term.person.default.yml b/modules/controlled_access_terms_default_configuration/config/install/core.entity_form_display.taxonomy_term.person.default.yml index 9d7b8b9..82689d7 100644 --- a/modules/controlled_access_terms_default_configuration/config/install/core.entity_form_display.taxonomy_term.person.default.yml +++ b/modules/controlled_access_terms_default_configuration/config/install/core.entity_form_display.taxonomy_term.person.default.yml @@ -42,7 +42,7 @@ content: strict_dates: false intervals: false third_party_settings: { } - type: text_edtf + type: edtf_default region: content field_cat_date_end: weight: 27 @@ -50,7 +50,7 @@ content: strict_dates: false intervals: false third_party_settings: { } - type: text_edtf + type: edtf_default region: content field_person_alternate_names: weight: 3 diff --git a/modules/controlled_access_terms_default_configuration/config/install/core.entity_view_display.taxonomy_term.corporate_body.default.yml b/modules/controlled_access_terms_default_configuration/config/install/core.entity_view_display.taxonomy_term.corporate_body.default.yml index 3e49437..3133cd5 100644 --- a/modules/controlled_access_terms_default_configuration/config/install/core.entity_view_display.taxonomy_term.corporate_body.default.yml +++ b/modules/controlled_access_terms_default_configuration/config/install/core.entity_view_display.taxonomy_term.corporate_body.default.yml @@ -47,7 +47,7 @@ content: day_format: dd season_hemisphere: north third_party_settings: { } - type: text_edtf_human + type: edtf_default region: content field_cat_date_end: weight: 3 @@ -59,7 +59,7 @@ content: day_format: dd season_hemisphere: north third_party_settings: { } - type: text_edtf_human + type: edtf_default region: content field_corp_alt_name: weight: 4 diff --git a/modules/controlled_access_terms_default_configuration/config/install/core.entity_view_display.taxonomy_term.family.default.yml b/modules/controlled_access_terms_default_configuration/config/install/core.entity_view_display.taxonomy_term.family.default.yml index 05f66fd..05d4f07 100644 --- a/modules/controlled_access_terms_default_configuration/config/install/core.entity_view_display.taxonomy_term.family.default.yml +++ b/modules/controlled_access_terms_default_configuration/config/install/core.entity_view_display.taxonomy_term.family.default.yml @@ -44,7 +44,7 @@ content: day_format: dd season_hemisphere: north third_party_settings: { } - type: text_edtf_human + type: edtf_default region: content field_cat_date_end: weight: 9 @@ -56,7 +56,7 @@ content: day_format: dd season_hemisphere: north third_party_settings: { } - type: text_edtf_human + type: edtf_default region: content field_relationships: weight: 11 diff --git a/modules/controlled_access_terms_default_configuration/config/install/core.entity_view_display.taxonomy_term.person.default.yml b/modules/controlled_access_terms_default_configuration/config/install/core.entity_view_display.taxonomy_term.person.default.yml index c53f09e..5f7245f 100644 --- a/modules/controlled_access_terms_default_configuration/config/install/core.entity_view_display.taxonomy_term.person.default.yml +++ b/modules/controlled_access_terms_default_configuration/config/install/core.entity_view_display.taxonomy_term.person.default.yml @@ -47,7 +47,7 @@ content: day_format: dd season_hemisphere: north third_party_settings: { } - type: text_edtf_human + type: edtf_default region: content field_cat_date_end: weight: 7 @@ -59,7 +59,7 @@ content: day_format: dd season_hemisphere: north third_party_settings: { } - type: text_edtf_human + type: edtf_default region: content field_person_alternate_names: weight: 3 diff --git a/modules/controlled_access_terms_default_configuration/config/install/field.field.taxonomy_term.corporate_body.field_cat_date_begin.yml b/modules/controlled_access_terms_default_configuration/config/install/field.field.taxonomy_term.corporate_body.field_cat_date_begin.yml index 556e6ce..723c616 100644 --- a/modules/controlled_access_terms_default_configuration/config/install/field.field.taxonomy_term.corporate_body.field_cat_date_begin.yml +++ b/modules/controlled_access_terms_default_configuration/config/install/field.field.taxonomy_term.corporate_body.field_cat_date_begin.yml @@ -15,4 +15,4 @@ translatable: false default_value: { } default_value_callback: '' settings: { } -field_type: string +field_type: edtf diff --git a/modules/controlled_access_terms_default_configuration/config/install/field.field.taxonomy_term.corporate_body.field_cat_date_end.yml b/modules/controlled_access_terms_default_configuration/config/install/field.field.taxonomy_term.corporate_body.field_cat_date_end.yml index f9cfe7c..cb67890 100644 --- a/modules/controlled_access_terms_default_configuration/config/install/field.field.taxonomy_term.corporate_body.field_cat_date_end.yml +++ b/modules/controlled_access_terms_default_configuration/config/install/field.field.taxonomy_term.corporate_body.field_cat_date_end.yml @@ -15,4 +15,4 @@ translatable: true default_value: { } default_value_callback: '' settings: { } -field_type: string +field_type: edtf diff --git a/modules/controlled_access_terms_default_configuration/config/install/field.field.taxonomy_term.family.field_cat_date_begin.yml b/modules/controlled_access_terms_default_configuration/config/install/field.field.taxonomy_term.family.field_cat_date_begin.yml index 2428ea4..58ab96f 100644 --- a/modules/controlled_access_terms_default_configuration/config/install/field.field.taxonomy_term.family.field_cat_date_begin.yml +++ b/modules/controlled_access_terms_default_configuration/config/install/field.field.taxonomy_term.family.field_cat_date_begin.yml @@ -15,4 +15,4 @@ translatable: false default_value: { } default_value_callback: '' settings: { } -field_type: string +field_type: edtf diff --git a/modules/controlled_access_terms_default_configuration/config/install/field.field.taxonomy_term.family.field_cat_date_end.yml b/modules/controlled_access_terms_default_configuration/config/install/field.field.taxonomy_term.family.field_cat_date_end.yml index b92fa70..2db627d 100644 --- a/modules/controlled_access_terms_default_configuration/config/install/field.field.taxonomy_term.family.field_cat_date_end.yml +++ b/modules/controlled_access_terms_default_configuration/config/install/field.field.taxonomy_term.family.field_cat_date_end.yml @@ -15,4 +15,4 @@ translatable: true default_value: { } default_value_callback: '' settings: { } -field_type: string +field_type: edtf diff --git a/modules/controlled_access_terms_default_configuration/config/install/field.field.taxonomy_term.person.field_cat_date_begin.yml b/modules/controlled_access_terms_default_configuration/config/install/field.field.taxonomy_term.person.field_cat_date_begin.yml index 3f576b7..eb1064c 100644 --- a/modules/controlled_access_terms_default_configuration/config/install/field.field.taxonomy_term.person.field_cat_date_begin.yml +++ b/modules/controlled_access_terms_default_configuration/config/install/field.field.taxonomy_term.person.field_cat_date_begin.yml @@ -15,4 +15,4 @@ translatable: false default_value: { } default_value_callback: '' settings: { } -field_type: string +field_type: edtf diff --git a/modules/controlled_access_terms_default_configuration/config/install/field.field.taxonomy_term.person.field_cat_date_end.yml b/modules/controlled_access_terms_default_configuration/config/install/field.field.taxonomy_term.person.field_cat_date_end.yml index 99a3201..ca4e79f 100644 --- a/modules/controlled_access_terms_default_configuration/config/install/field.field.taxonomy_term.person.field_cat_date_end.yml +++ b/modules/controlled_access_terms_default_configuration/config/install/field.field.taxonomy_term.person.field_cat_date_end.yml @@ -15,4 +15,4 @@ translatable: false default_value: { } default_value_callback: '' settings: { } -field_type: string +field_type: edtf diff --git a/modules/controlled_access_terms_default_configuration/config/install/field.storage.taxonomy_term.field_cat_date_begin.yml b/modules/controlled_access_terms_default_configuration/config/install/field.storage.taxonomy_term.field_cat_date_begin.yml index 751d041..d1545e5 100644 --- a/modules/controlled_access_terms_default_configuration/config/install/field.storage.taxonomy_term.field_cat_date_begin.yml +++ b/modules/controlled_access_terms_default_configuration/config/install/field.storage.taxonomy_term.field_cat_date_begin.yml @@ -6,7 +6,7 @@ dependencies: id: taxonomy_term.field_cat_date_begin field_name: field_cat_date_begin entity_type: taxonomy_term -type: string +type: edtf settings: max_length: 60 is_ascii: false diff --git a/modules/controlled_access_terms_default_configuration/config/install/field.storage.taxonomy_term.field_cat_date_end.yml b/modules/controlled_access_terms_default_configuration/config/install/field.storage.taxonomy_term.field_cat_date_end.yml index 4191c39..76cb22f 100644 --- a/modules/controlled_access_terms_default_configuration/config/install/field.storage.taxonomy_term.field_cat_date_end.yml +++ b/modules/controlled_access_terms_default_configuration/config/install/field.storage.taxonomy_term.field_cat_date_end.yml @@ -6,7 +6,7 @@ dependencies: id: taxonomy_term.field_cat_date_end field_name: field_cat_date_end entity_type: taxonomy_term -type: string +type: edtf settings: max_length: 60 is_ascii: false diff --git a/modules/controlled_access_terms_default_configuration/config/install/field.storage.taxonomy_term.field_corp_dissolution_date.yml b/modules/controlled_access_terms_default_configuration/config/install/field.storage.taxonomy_term.field_corp_dissolution_date.yml deleted file mode 100644 index 3eb84d0..0000000 --- a/modules/controlled_access_terms_default_configuration/config/install/field.storage.taxonomy_term.field_corp_dissolution_date.yml +++ /dev/null @@ -1,20 +0,0 @@ -langcode: en -status: true -dependencies: - module: - - taxonomy -id: taxonomy_term.field_corp_dissolution_date -field_name: field_corp_dissolution_date -entity_type: taxonomy_term -type: string -settings: - max_length: 60 - is_ascii: false - case_sensitive: false -module: core -locked: false -cardinality: 1 -translatable: true -indexes: { } -persist_with_no_fields: false -custom_storage: false diff --git a/modules/controlled_access_terms_default_configuration/config/install/field.storage.taxonomy_term.field_corp_founding_date.yml b/modules/controlled_access_terms_default_configuration/config/install/field.storage.taxonomy_term.field_corp_founding_date.yml deleted file mode 100644 index 55798c6..0000000 --- a/modules/controlled_access_terms_default_configuration/config/install/field.storage.taxonomy_term.field_corp_founding_date.yml +++ /dev/null @@ -1,20 +0,0 @@ -langcode: en -status: true -dependencies: - module: - - taxonomy -id: taxonomy_term.field_corp_founding_date -field_name: field_corp_founding_date -entity_type: taxonomy_term -type: string -settings: - max_length: 60 - is_ascii: false - case_sensitive: false -module: core -locked: false -cardinality: 1 -translatable: true -indexes: { } -persist_with_no_fields: false -custom_storage: false diff --git a/src/EDTFConverter.php b/src/EDTFConverter.php index a1fd726..85a278e 100644 --- a/src/EDTFConverter.php +++ b/src/EDTFConverter.php @@ -54,7 +54,7 @@ class EDTFConverter extends CommonDataConverter { * @return string * Returns the ISO 8601 timestamp. */ - public static function dateIso8601Value(array $data) { + public static function datetimeIso8601Value(array $data) { $date = explode('/', $data['value'])[0]; // Strip approximations/uncertainty. @@ -67,13 +67,56 @@ public static function dateIso8601Value(array $data) { $date = str_replace('u', '0', $date); // Seasons map. - list($year, $month, $day) = explode('-', $date, 3); + return EDTFConverter::seasonsMap($date) . 'T00:00:00'; + + } + + /** + * Converts an EDTF text field into an ISO 8601 timestamp string. + * + * It assumes the earliest valid date for approximations and intervals. + * + * @param array $data + * The array containing the 'value' element. + * + * @return string + * Returns the ISO 8601 date. + */ + public static function dateIso8601Value(array $data) { + $date = explode('/', $data['value'])[0]; + + // Strip approximations/uncertainty. + $date = str_replace(['?', '~'], '', $date); + + // Remove unspecified. + // Month/day. + $date = str_replace('-uu', '', $date); + // Zero-Year in decade/century. + $date = str_replace('u', '0', $date); + + // Seasons map. + return EDTFConverter::seasonsMap($date); + + } + + /** + * Converts a numeric season into a numeric month. + * + * @param string $date + * The date string to convert. + * + * @return string + * Returns the ISO 8601 date with the correct month. + */ + protected static function seasonsMap(string $date) { + $date_parts[] = explode('-', $date, 3); // Digit Seasons. - if (in_array($month, ['21', '22', '23', '24'])) { + if ((count($date_parts) > 1) && + in_array($date_parts[1], ['21', '22', '23', '24'])) { // TODO: Make hemisphere seasons configurable. $season_mapping = $seasonMapNorth; - $month = $season_mapping[$month]; - $date = implode('-', array_filter([$year, $month, $day])); + $date_parts[1] = $season_mapping[$date_parts[1]]; + $date = implode('-', array_filter($date_parts)); } return $date; diff --git a/src/Plugin/Field/FieldFormatter/TextEDTFHumanFormatter.php b/src/Plugin/Field/FieldFormatter/EDTFFormatter.php similarity index 97% rename from src/Plugin/Field/FieldFormatter/TextEDTFHumanFormatter.php rename to src/Plugin/Field/FieldFormatter/EDTFFormatter.php index f6a4f5b..0720c36 100644 --- a/src/Plugin/Field/FieldFormatter/TextEDTFHumanFormatter.php +++ b/src/Plugin/Field/FieldFormatter/EDTFFormatter.php @@ -7,19 +7,19 @@ use Drupal\Core\Form\FormStateInterface; /** - * Plugin implementation of the 'TextEDTFHumanFormatter'. + * Plugin implementation of the 'TextEDTFFormatter'. * * Only supports EDTF through level 1. * * @FieldFormatter( - * id = "text_edtf_human", - * label = @Translation("EDTF (L1) for Humans"), + * id = "edtf_default", + * label = @Translation("Default EDTF formatter"), * field_types = { - * "string" + * "edtf" * } * ) */ -class TextEDTFHumanFormatter extends FormatterBase { +class EDTFFormatter extends FormatterBase { /** * Month/Season to text map. @@ -158,7 +158,7 @@ public function settingsForm(array $form, FormStateInterface $form_state) { '#title' => t('Hemisphere Seasons'), '#type' => 'select', '#default_value' => $this->getSetting('season_hemisphere'), - '#description' => t("Seasons don't have digit months so we map them + '#description' => t("Seasons don't have digit months so we map them to their respective equinox and solstice months. Select a hemisphere to use for the mapping."), '#options' => [ diff --git a/src/Plugin/Field/FieldFormatter/TextEDTFiso8601.php b/src/Plugin/Field/FieldFormatter/TextEDTFiso8601.php deleted file mode 100644 index 1dfaf5d..0000000 --- a/src/Plugin/Field/FieldFormatter/TextEDTFiso8601.php +++ /dev/null @@ -1,138 +0,0 @@ - March. - '21' => '03', - // Summer => June. - '22' => '06', - // Autumn => September. - '23' => '09', - // Winter => December. - '24' => '12', - ]; - - /** - * Southern hemisphere season map. - * - * @var array - */ - private $seasonMapSouth = [ - // Spring => September. - '21' => '03', - // Summer => December. - '22' => '06', - // Autumn => March. - '23' => '09', - // Winter => June. - '24' => '12', - ]; - - /** - * {@inheritdoc} - */ - public static function defaultSettings() { - return [ - // Northern bias, sorry. - 'season_hemisphere' => 'north', - ] + parent::defaultSettings(); - } - - /** - * {@inheritdoc} - */ - public function settingsForm(array $form, FormStateInterface $form_state) { - $form['season_hemisphere'] = [ - '#title' => t('Hemisphere Seasons'), - '#type' => 'select', - '#default_value' => $this->getSetting('season_hemisphere'), - '#description' => t("Seasons aren't currently supported by iso 8601. - We map them to their respective equinox and - solstice months. Select a hemisphere to use for - the mapping."), - '#options' => [ - 'north' => t('Northern Hemisphere'), - 'south' => t('Southern Hemisphere'), - ], - ]; - return $form; - } - - /** - * {@inheritdoc} - */ - public function settingsSummary() { - $summary = []; - if ($this->getSetting('strict_dates') === 'south') { - $summary[] = t('Seasons mapped to the southern hemisphere.'); - } - return $summary; - } - - /** - * {@inheritdoc} - */ - public function viewElements(FieldItemListInterface $items, $langcode) { - $element = []; - $settings = $this->getSettings(); - - foreach ($items as $delta => $item) { - // Interval. - list($begin, $end) = explode('/', $item->value); - // End is currently ignored. - // Strip approximations/uncertainty. - $begin = str_replace(['?', '~'], '', $begin); - - // Replace unspecified. - // Month/day. - $begin = str_replace('-uu', '-01', $begin); - // Zero-Year in decade/century. - $begin = str_replace('u', '0', $begin); - - // Seasons map. - list($year, $month, $day) = explode('-', $begin, 3); - // Digit Seasons. - if (in_array($month, ['21', '22', '23', '24'])) { - $season_mapping = ($settings['season_hemisphere'] === 'north' ? $this->seasonMapNorth : $this->seasonMapSouth); - $month = $season_mapping[$month]; - $begin = implode('-', array_filter([$year, $month, $day])); - } - - $element[$delta] = ['#markup' => $begin]; - } - return $element; - } - -} diff --git a/src/Plugin/Field/FieldType/ExtendedDateTimeFormat.php b/src/Plugin/Field/FieldType/ExtendedDateTimeFormat.php new file mode 100644 index 0000000..900e4d2 --- /dev/null +++ b/src/Plugin/Field/FieldType/ExtendedDateTimeFormat.php @@ -0,0 +1,21 @@ +t( - 'Negative dates, and the level 1 features unspecified dates, + 'Negative dates, and the level 1 features unspecified dates, extended years, and seasons are not supported with strict date checking.' ); diff --git a/src/Plugin/Field/FieldWidget/TextDateWidget.php b/src/Plugin/Field/FieldWidget/TextDateWidget.php deleted file mode 100644 index fe1ab5e..0000000 --- a/src/Plugin/Field/FieldWidget/TextDateWidget.php +++ /dev/null @@ -1,106 +0,0 @@ - 'Y-m-d', - 'strict_dates' => TRUE, - ] + parent::defaultSettings(); - } - - /** - * {@inheritdoc} - */ - public function settingsForm(array $form, FormStateInterface $form_state) { - $element = parent::settingsForm($form, $form_state); - $element['date_format'] = [ - '#type' => 'textfield', - '#title' => $this->t('PHP DateTime Format String.'), - '#description' => $this->t('See PHP DateTime Documentation for details.', ['@phpdate' => 'http://php.net/manual/en/datetime.createfromformat.php']), - '#default_value' => $this->getSetting('date_format'), - ]; - $element['strict_dates'] = [ - '#type' => 'checkbox', - '#title' => $this->t('Ensure date values are valid.'), - '#default_value' => $this->getSetting('strict_dates'), - ]; - return $element; - } - - /** - * {@inheritdoc} - */ - public function settingsSummary() { - $summary = []; - - $summary[] = t('Date Format: @format', ['@format' => $this->getSetting('date_format')]); - - if ($this->getSetting('strict_dates')) { - $summary[] = t('Strict dates enabled'); - } - - return $summary; - } - - /** - * {@inheritdoc} - */ - public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) { - $element['value'] = $element + [ - '#type' => 'textfield', - '#default_value' => isset($items[$delta]->value) ? $items[$delta]->value : NULL, - '#placeholder' => $this - ->getSetting('placeholder'), - '#element_validate' => [ - [$this, 'validate'], - ], - ]; - return $element; - } - - /** - * Validate date format compliance. - */ - public function validate($element, FormStateInterface $form_state) { - $value = $element['#value']; - if (strlen($value) == 0) { - $form_state->setValueForElement($element, ''); - return; - } - $date_format = $this->getSetting('date_format'); - $date = DateTime::createFromFormat($date_format, $value); - if (!$date) { - $form_state->setError($element, t("Date must match the pattern @format", - ['@format' => $date_format])); - } - $errors = DateTime::getLastErrors(); - if ($this->getSetting('strict_dates') && !empty($errors['warning_count'])) { - $form_state->setError($element, t('Strictly speaking, the date "@value" is invalid!', - ['@value' => $value])); - } - } - -}