From 013f2c13d3572f23a06de8629e876d281df9ddab Mon Sep 17 00:00:00 2001
From: Kaise Lafrai <56809719+kaise-lafrai@users.noreply.github.com>
Date: Tue, 21 May 2024 12:25:31 -0400
Subject: [PATCH] Additional data types added to the data dictionary form
(#4173)
---
.../src/Fields/FieldAddCreation.php | 5 +-
.../src/Fields/FieldCallbacks.php | 4 +-
.../src/Fields/FieldEditCreation.php | 8 +-
.../src/Fields/FieldOperations.php | 98 ++++-----
.../src/Fields/FieldValues.php | 66 +++++-
.../Unit/DataDictionaryWidgetBuildTest.php | 9 +-
.../tests/src/Unit/FieldCallbacksTest.php | 199 ++++++++++++++++++
7 files changed, 325 insertions(+), 64 deletions(-)
create mode 100644 modules/data_dictionary_widget/tests/src/Unit/FieldCallbacksTest.php
diff --git a/modules/data_dictionary_widget/src/Fields/FieldAddCreation.php b/modules/data_dictionary_widget/src/Fields/FieldAddCreation.php
index 3017edd480..276fd014c2 100644
--- a/modules/data_dictionary_widget/src/Fields/FieldAddCreation.php
+++ b/modules/data_dictionary_widget/src/Fields/FieldAddCreation.php
@@ -63,8 +63,11 @@ private static function createType() {
'#options' => [
'string' => t('String'),
'date' => t('Date'),
+ 'datetime' => t('Datetime'),
'integer' => t('Integer'),
'number' => t('Number'),
+ 'year' => t('Year'),
+ 'boolean' => t('Boolean'),
],
'#ajax' => [
'callback' => '\Drupal\data_dictionary_widget\Fields\FieldCallbacks::updateFormatOptions',
@@ -83,7 +86,7 @@ private static function createFormat() {
'#type' => 'select',
'#required' => TRUE,
'#title' => 'Format',
- '#description' => FieldOperations::generateFormatDescription("string"),
+ '#description' => FieldOperations::generateFormats("string", "description"),
'#default_value' => 'default',
'#prefix' => '
',
'#suffix' => '
',
diff --git a/modules/data_dictionary_widget/src/Fields/FieldCallbacks.php b/modules/data_dictionary_widget/src/Fields/FieldCallbacks.php
index fd755db6a2..a22bf5f1fe 100644
--- a/modules/data_dictionary_widget/src/Fields/FieldCallbacks.php
+++ b/modules/data_dictionary_widget/src/Fields/FieldCallbacks.php
@@ -27,8 +27,8 @@ public static function updateFormatOptions(array &$form, FormStateInterface $for
$data_type = $field[0]["dictionary_fields"]["data"][$field_index]["field_collection"]["type"] ?? 'string';
}
- $format_field['#description'] = FieldOperations::generateFormatDescription($data_type);
- $options = FieldOperations::setFormatOptions($data_type);
+ $format_field['#description'] = FieldOperations::generateFormats($data_type, "description");
+ $options = FieldOperations::generateFormats($data_type, "options");
$format_field["#options"] = $options;
diff --git a/modules/data_dictionary_widget/src/Fields/FieldEditCreation.php b/modules/data_dictionary_widget/src/Fields/FieldEditCreation.php
index e48b44a7dd..78fee533bc 100644
--- a/modules/data_dictionary_widget/src/Fields/FieldEditCreation.php
+++ b/modules/data_dictionary_widget/src/Fields/FieldEditCreation.php
@@ -63,15 +63,15 @@ private static function createType($key, $current_fields) {
* Create Format field.
*/
private static function createFormat($key, $current_fields) {
- $format_options = FieldOperations::setFormatOptions($current_fields[$key]['type']);
- $value = in_array($current_fields[$key]['format'], $format_options) ? $current_fields[$key]['format'] : 'other';
+ $format_options = FieldOperations::generateFormats($current_fields[$key]['type'], "options");
+ $value = in_array($current_fields[$key]['format'], $format_options, TRUE) ? $current_fields[$key]['format'] : 'other';
return [
'#name' => 'field_json_metadata[0][dictionary_fields][data][' . $key . '][field_collection][format]',
'#type' => 'select',
'#required' => TRUE,
'#title' => 'Format',
'#default_value' => 'default',
- '#description' => FieldOperations::generateFormatDescription($current_fields[$key]['type']),
+ '#description' => FieldOperations::generateFormats($current_fields[$key]['type'], "description"),
'#value' => $value,
'#prefix' => '',
'#suffix' => '
',
@@ -84,7 +84,7 @@ private static function createFormat($key, $current_fields) {
* Create Format Other field.
*/
private static function createFormatOther($key, $current_fields) {
- $format_options = FieldOperations::setFormatOptions($current_fields[$key]['type']);
+ $format_options = FieldOperations::generateFormats($current_fields[$key]['type'], "options");
$value = !in_array($current_fields[$key]['format'], $format_options) ? $current_fields[$key]['format'] : NULL;
return [
diff --git a/modules/data_dictionary_widget/src/Fields/FieldOperations.php b/modules/data_dictionary_widget/src/Fields/FieldOperations.php
index 338898ac22..f084842636 100644
--- a/modules/data_dictionary_widget/src/Fields/FieldOperations.php
+++ b/modules/data_dictionary_widget/src/Fields/FieldOperations.php
@@ -62,60 +62,51 @@ public static function setAjaxElements(array $dictionaryFields) {
*
* @param string $dataType
* Field data type.
+ * @param string $property
+ * Property of array.
*
- * @return string
- * Description information.
+ * @return string|array
+ * Description information or options list.
+ *
+ * @throws \InvalidArgumentException
*/
- public static function generateFormatDescription($dataType) {
+ public static function generateFormats($dataType, $property) {
$description = "The format of the data in this field. Supported formats depend on the specified field type:
";
- if ($dataType === 'string') {
- $description .= FieldValues::returnStringInfo('description');
- }
+ switch ($dataType) {
+ case 'string':
+ $info = FieldValues::returnStringInfo($property);
+ break;
- if ($dataType === 'date') {
- $description = FieldValues::returnDateInfo('description');
- }
+ case 'date':
+ $info = FieldValues::returnDateInfo($property);
+ break;
- if ($dataType === 'integer') {
- $description .= FieldValues::returnIntegerInfo('description');
- }
+ case 'datetime':
+ $info = FieldValues::returnDateTimeInfo($property);
+ break;
- if ($dataType === 'number') {
- $description .= FieldValues::returnNumberInfo('description');
- }
- return $description;
- }
+ case 'integer':
+ $info = FieldValues::returnIntegerInfo($property);
+ break;
- /**
- * Function to generate the options for the "Format" field.
- *
- * @param string $dataType
- * Field data type.
- *
- * @return array
- * List of format options.
- */
- public static function setFormatOptions($dataType) {
+ case 'number':
+ $info = FieldValues::returnNumberInfo($property);
+ break;
- if ($dataType === 'string') {
- $options = FieldValues::returnStringInfo('options');
- }
+ case 'year':
+ $info = FieldValues::returnYearInfo($property);
+ break;
- if ($dataType === 'date') {
- $options = FieldValues::returnDateInfo('options');
- }
-
- if ($dataType === 'integer') {
- $options = FieldValues::returnIntegerInfo('options');
- }
+ case 'boolean':
+ $info = FieldValues::returnBooleanInfo($property);
+ break;
- if ($dataType === 'number') {
- $options = FieldValues::returnNumberInfo('options');
+ default:
+ throw new \InvalidArgumentException("Unexpected data type: $dataType");
}
- return $options;
-
+ return ($property === "description") ? ($description . $info) : $info;
}
/**
@@ -169,8 +160,11 @@ public static function setTypeOptions() {
return [
'string' => t('String'),
'date' => t('Date'),
+ 'datetime' => t('Datetime'),
'integer' => t('Integer'),
'number' => t('Number'),
+ 'year' => t('Year'),
+ 'boolean' => t('Boolean'),
];
}
@@ -290,8 +284,8 @@ public static function resetAllFormatOptions(array &$form, FormStateInterface $f
]);
if ($type) {
- $form["field_json_metadata"]["widget"][0]["dictionary_fields"]["edit_fields"][$index]["format"]["#options"] = FieldOperations::setFormatOptions($type);
- $form["field_json_metadata"]["widget"][0]["dictionary_fields"]["edit_fields"][$index]["format"]["#description"] = FieldOperations::generateFormatDescription($type);
+ $form["field_json_metadata"]["widget"][0]["dictionary_fields"]["edit_fields"][$index]["format"]["#options"] = FieldOperations::generateFormats($type, "options");
+ $form["field_json_metadata"]["widget"][0]["dictionary_fields"]["edit_fields"][$index]["format"]["#description"] = FieldOperations::generateFormats($type, "description");
}
}
@@ -310,10 +304,20 @@ public static function resetAllFormatOptions(array &$form, FormStateInterface $f
* The form array to be modified.
*/
public static function resetDateFormatOptions(array &$form) {
- $field_collection = isset($form["field_json_metadata"]["widget"][0]["dictionary_fields"]["field_collection"]);
- if ($field_collection && $form["field_json_metadata"]["widget"][0]["dictionary_fields"]["field_collection"]["group"]["type"]["#value"] === "date") {
- $form["field_json_metadata"]["widget"][0]["dictionary_fields"]["field_collection"]["group"]["format"]["#options"] = FieldValues::returnDateInfo('options');
- $form["field_json_metadata"]["widget"][0]["dictionary_fields"]["field_collection"]["group"]["format"]["#description"] = FieldValues::returnDateInfo('description');
+ $data_type = $form["field_json_metadata"]["widget"][0]["dictionary_fields"]["field_collection"]["group"]["type"]["#value"] ?? NULL;
+
+ if (!$data_type || ($data_type !== "date" && $data_type !== "datetime")) {
+ return;
+ }
+
+ $options_method = ($data_type === "date") ? 'returnDateInfo' : 'returnDateTimeInfo';
+ $options = FieldValues::$options_method('options');
+ $description = FieldValues::$options_method('description');
+
+ if ($options && $description) {
+ $format_field =& $form["field_json_metadata"]["widget"][0]["dictionary_fields"]["field_collection"]["group"]["format"];
+ $format_field["#options"] = $options;
+ $format_field["#description"] = $description;
}
}
diff --git a/modules/data_dictionary_widget/src/Fields/FieldValues.php b/modules/data_dictionary_widget/src/Fields/FieldValues.php
index 3cdc39bec7..f3207c12de 100644
--- a/modules/data_dictionary_widget/src/Fields/FieldValues.php
+++ b/modules/data_dictionary_widget/src/Fields/FieldValues.php
@@ -26,7 +26,7 @@ public static function updateValues($field_index, $update_values, $current_field
}
/**
- * Retrun information about the string field option.
+ * Return information about the string field option.
*/
public static function returnStringInfo($type) {
if ($type == 'options') {
@@ -52,7 +52,7 @@ public static function returnStringInfo($type) {
}
/**
- * Retrun information about the date field option.
+ * Return information about the date field option.
*/
public static function returnDateInfo($type) {
if ($type == 'options') {
@@ -74,7 +74,29 @@ public static function returnDateInfo($type) {
}
/**
- * Retrun information about the integer field option.
+ * Return information about the datetime field option.
+ */
+ public static function returnDateTimeInfo($type) {
+ if ($type == 'options') {
+ return [
+ 'default' => 'default',
+ 'any' => 'any',
+ 'other' => 'other',
+ ];
+ }
+ elseif ($type == 'description') {
+ return "
+
+ - default: An ISO8601 format string of datetime.
+ - any: Any parsable representation of a date. The implementing library can attept to parse the datetime via a range of strategies.
+ - other: If your date values follow a collective but non-ISO8601 pattern, select this option and define the incoming format using the syntax of C / Python strftime.
+ For example, if your data had dates formatted as MM/DD/YYYY, you would enter %m/%d/%Y into the Other format field.
+
";
+ }
+ }
+
+ /**
+ * Return information about the integer field option.
*/
public static function returnIntegerInfo($type) {
if ($type == 'options') {
@@ -91,7 +113,7 @@ public static function returnIntegerInfo($type) {
}
/**
- * Retrun information about the number field option.
+ * Return information about the number field option.
*/
public static function returnNumberInfo($type) {
if ($type == 'options') {
@@ -102,7 +124,41 @@ public static function returnNumberInfo($type) {
elseif ($type == 'description') {
return "
- - default: Any valid string.
+ - default: An exact fixed-point number. No non-numeric characters allowed other than the decimal.
+
";
+ }
+ }
+
+ /**
+ * Return information about the year field option.
+ */
+ public static function returnYearInfo($type) {
+ if ($type == 'options') {
+ return [
+ 'default' => 'default',
+ ];
+ }
+ elseif ($type == 'description') {
+ return "
+
+ - default: 4-digit numbers in the range 1901 to 2155.
+
";
+ }
+ }
+
+ /**
+ * Return information about the year field option.
+ */
+ public static function returnBooleanInfo($type) {
+ if ($type == 'options') {
+ return [
+ 'default' => 'default',
+ ];
+ }
+ elseif ($type == 'description') {
+ return "
+
+ - default: 1/0 values, or True/False values (not case sensitive).
";
}
}
diff --git a/modules/data_dictionary_widget/tests/src/Unit/DataDictionaryWidgetBuildTest.php b/modules/data_dictionary_widget/tests/src/Unit/DataDictionaryWidgetBuildTest.php
index d2ac08f987..45106113ad 100644
--- a/modules/data_dictionary_widget/tests/src/Unit/DataDictionaryWidgetBuildTest.php
+++ b/modules/data_dictionary_widget/tests/src/Unit/DataDictionaryWidgetBuildTest.php
@@ -4,12 +4,9 @@
use PHPUnit\Framework\TestCase;
use Drupal\data_dictionary_widget\Fields\FieldAddCreation;
-use Drupal\data_dictionary_widget\Fields\FieldButtons;
use Drupal\data_dictionary_widget\Fields\FieldCallbacks;
use Drupal\data_dictionary_widget\Fields\FieldCreation;
-use Drupal\data_dictionary_widget\Fields\FieldEditCreation;
use Drupal\data_dictionary_widget\Fields\FieldOperations;
-use Drupal\data_dictionary_widget\Fields\FieldValues;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Entity\EntityFormInterface;
@@ -212,6 +209,8 @@ public function testAddNewFieldDictionaryWidget() {
]
];
+
+
$dataDictionaryWidget = new DataDictionaryWidget (
$plugin_id,
$plugin_definition,
@@ -392,8 +391,8 @@ public function testEditDataDictionaryField() {
$user_input = [
'field_json_metadata' => [
0 => [
- 'identifier' => 'Kaise',
- 'title' => 'Kaise',
+ 'identifier' => 'test_identifier',
+ 'title' => 'test_title',
'dictionary_fields' => [
'data' => [
0 => [
diff --git a/modules/data_dictionary_widget/tests/src/Unit/FieldCallbacksTest.php b/modules/data_dictionary_widget/tests/src/Unit/FieldCallbacksTest.php
new file mode 100644
index 0000000000..79288bda09
--- /dev/null
+++ b/modules/data_dictionary_widget/tests/src/Unit/FieldCallbacksTest.php
@@ -0,0 +1,199 @@
+createMock(FormStateInterface::class);
+
+ $types = ['string', 'date', 'datetime', 'integer', 'number', 'year', 'boolean'];
+
+ $field_json_metadata_string = [
+ [
+ 'identifier' => 'test_identifier',
+ 'title' => 'test_title',
+ 'dictionary_fields' => [
+ 'field_collection' => [
+ 'group' => [
+ 'name' => 'test_edit',
+ 'title' => 'test_edit',
+ 'type' => 'string',
+ 'format' => 'default',
+ 'format_other' => '',
+ 'description' => 'test_edit',
+ ]
+ ]
+ ]
+ ]
+ ];
+
+ $field_json_metadata_date = [
+ [
+ 'identifier' => 'test_identifier',
+ 'title' => 'test_title',
+ 'dictionary_fields' => [
+ 'field_collection' => [
+ 'group' => [
+ 'name' => 'test_edit',
+ 'title' => 'test_edit',
+ 'type' => 'date',
+ 'format' => 'default',
+ 'format_other' => '',
+ 'description' => 'test_edit',
+ ]
+ ]
+ ]
+ ]
+ ];
+
+ $field_json_metadata_datetime = [
+ [
+ 'identifier' => 'test_identifier',
+ 'title' => 'test_title',
+ 'dictionary_fields' => [
+ 'field_collection' => [
+ 'group' => [
+ 'name' => 'test_edit',
+ 'title' => 'test_edit',
+ 'type' => 'datetime',
+ 'format' => 'default',
+ 'format_other' => '',
+ 'description' => 'test_edit',
+ ]
+ ]
+ ]
+ ]
+ ];
+
+ $field_json_metadata_integer = [
+ [
+ 'identifier' => 'test_identifier',
+ 'title' => 'test_title',
+ 'dictionary_fields' => [
+ 'field_collection' => [
+ 'group' => [
+ 'name' => 'test_edit',
+ 'title' => 'test_edit',
+ 'type' => 'integer',
+ 'format' => 'default',
+ 'format_other' => '',
+ 'description' => 'test_edit',
+ ]
+ ]
+ ]
+ ]
+ ];
+
+ $field_json_metadata_number = [
+ [
+ 'identifier' => 'test_identifier',
+ 'title' => 'test_title',
+ 'dictionary_fields' => [
+ 'field_collection' => [
+ 'group' => [
+ 'name' => 'test_edit',
+ 'title' => 'test_edit',
+ 'type' => 'number',
+ 'format' => 'default',
+ 'format_other' => '',
+ 'description' => 'test_edit',
+ ]
+ ]
+ ]
+ ]
+ ];
+
+ $field_json_metadata_year = [
+ [
+ 'identifier' => 'test_identifier',
+ 'title' => 'test_title',
+ 'dictionary_fields' => [
+ 'field_collection' => [
+ 'group' => [
+ 'name' => 'test_edit',
+ 'title' => 'test_edit',
+ 'type' => 'year',
+ 'format' => 'default',
+ 'format_other' => '',
+ 'description' => 'test_edit',
+ ]
+ ]
+ ]
+ ]
+ ];
+
+ $field_json_metadata_boolean = [
+ [
+ 'identifier' => 'test_identifier',
+ 'title' => 'test_title',
+ 'dictionary_fields' => [
+ 'field_collection' => [
+ 'group' => [
+ 'name' => 'test_edit',
+ 'title' => 'test_edit',
+ 'type' => 'boolean',
+ 'format' => 'default',
+ 'format_other' => '',
+ 'description' => 'test_edit',
+ ]
+ ]
+ ]
+ ]
+ ];
+
+ $field_json_metadata_variables = [
+ 'string' => $field_json_metadata_string,
+ 'date' => $field_json_metadata_date,
+ 'datetime' => $field_json_metadata_datetime,
+ 'integer' => $field_json_metadata_integer,
+ 'number' => $field_json_metadata_number,
+ 'year' => $field_json_metadata_year,
+ 'boolean' => $field_json_metadata_boolean,
+ ];
+
+ $formState->method('getValue')
+ ->with(['field_json_metadata'])
+ ->willReturnOnConsecutiveCalls(
+ $field_json_metadata_string,
+ $field_json_metadata_date,
+ $field_json_metadata_datetime,
+ $field_json_metadata_integer,
+ $field_json_metadata_number,
+ $field_json_metadata_year,
+ $field_json_metadata_boolean
+ );
+
+ $trigger = ['#op' => 'type'];
+
+ $formState->expects($this->any())
+ ->method('getTriggeringElement')
+ ->willReturn($trigger);
+
+ $form["field_json_metadata"]["widget"][0]['dictionary_fields']["field_collection"]["group"]["format"] = [
+ '#description' => '',
+ '#options' => [],
+ ];
+
+ foreach ($types as $type) {
+ $format_field = FieldCallbacks::updateFormatOptions($form, $formState);
+ $field_json_metadata_type = $field_json_metadata_variables[$type];
+ $field_json_metadata = $field_json_metadata_type[0]['dictionary_fields']['field_collection']['group']['type'];
+
+ $this->assertEquals($type, $field_json_metadata);
+ $this->assertNotNull($format_field["#description"]);
+ $this->assertNotNull($format_field["#options"]);
+ }
+ }
+}
\ No newline at end of file