diff --git a/config/schema/strawberryfield.schema.yml b/config/schema/strawberryfield.schema.yml index 72a0142..b8a31d4 100644 --- a/config/schema/strawberryfield.schema.yml +++ b/config/schema/strawberryfield.schema.yml @@ -50,7 +50,10 @@ strawberryfield.strawberry_keynameprovider.jmespath: mapping: source_key: type: string - label: 'A Comma separated string containing one or more JMESPaths ' + label: 'A Comma separated string containing one or more JMESPaths' + is_date: + type: boolean + label: 'If the value should be considered and validated as a date' exposed_key: type: string label: 'The field property we expose for the Strawberryfield' diff --git a/src/Plugin/DataType/StrawberryValuesFromJson.php b/src/Plugin/DataType/StrawberryValuesFromJson.php index 59f48e5..2790238 100644 --- a/src/Plugin/DataType/StrawberryValuesFromJson.php +++ b/src/Plugin/DataType/StrawberryValuesFromJson.php @@ -36,7 +36,7 @@ class StrawberryValuesFromJson extends ItemList { */ protected $list = []; public function getValue() { - if ($this->processed == NULL) { + if ($this->processed === NULL) { $this->process(); } $values = []; @@ -79,6 +79,7 @@ public function process($langcode = NULL) $values[] = trim($flattened[$needle]); } $this->processed = array_values($values); + $this->list = []; foreach ($this->processed as $delta => $item) { $this->list[$delta] = $this->createItem($delta, $item); } diff --git a/src/Plugin/DataType/StrawberryValuesViaJmesPathFromJson.php b/src/Plugin/DataType/StrawberryValuesViaJmesPathFromJson.php index b9d615d..50dd358 100644 --- a/src/Plugin/DataType/StrawberryValuesViaJmesPathFromJson.php +++ b/src/Plugin/DataType/StrawberryValuesViaJmesPathFromJson.php @@ -9,6 +9,7 @@ use Drupal\Core\TypedData\Plugin\DataType\ItemList; use Drupal\strawberryfield\Plugin\Field\FieldType\StrawberryFieldItem; use Drupal\strawberryfield\Tools\StrawberryfieldJsonHelper; +use EDTF\EdtfFactory; class StrawberryValuesViaJmesPathFromJson extends ItemList { /** @@ -29,6 +30,7 @@ class StrawberryValuesViaJmesPathFromJson extends ItemList { * @var \Drupal\Core\TypedData\TypedDataInterface[] */ protected $list = []; + public function getValue() { if ($this->processed == NULL) { $this->process(); @@ -48,52 +50,67 @@ public function process($langcode = NULL) if ($this->computed == TRUE) { return; } - $values = []; $item = $this->getParent(); if (!empty($item->value)) { /* @var $item StrawberryFieldItem */ - $flattened = $item->provideFlatten(FALSE); $definition = $this->getDataDefinition(); // This key is passed by the property definition in the field class // jsonkey in this context is a string containing one or more // jmespath's separated by comma. $jmespaths = $definition['settings']['jsonkey']; + $is_date = $definition['settings']['is_date'] ?? FALSE; $jmespath_array = array_map('trim', explode(',', $jmespaths)); $jmespath_result = []; foreach ($jmespath_array as $jmespath) { $jmespath_result[] = $item->searchPath(trim($jmespath),FALSE); } $jmespath_result_to_expose = []; - - foreach ($jmespath_result as $item) { - if (is_array($item)) { - if (StrawberryfieldJsonHelper::arrayIsMultiSimple($item)) { - // @TODO should we allow unicode directly? - // If its multidimensional simple json encode as a string. - // We could also just get the first order values? - // @TODO, ask the team. - $jmespath_result_to_expose[] = json_encode($item, JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES); - } else { - $jmespath_result_to_expose = array_merge($jmespath_result_to_expose, $item); - } - + foreach ($jmespath_result as $item) { + if (is_array($item)) { + if (StrawberryfieldJsonHelper::arrayIsMultiSimple($item)) { + // @TODO should we allow unicode directly? + // If its multidimensional simple json encode as a string. + // We could also just get the first order values? + // @TODO, ask the team. + $jmespath_result_to_expose[] = json_encode($item, JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES); + } else { + $jmespath_result_to_expose = array_merge($jmespath_result_to_expose, $item); } - else { - // If a single value, simply cast to array - $jmespath_result_to_expose[] = $item; + } + else { + // If a single value, simply cast to array + $jmespath_result_to_expose[] = $item; + } + } + // This is an array, don't double nest to make the normalizer happy. + $jmespath_result_to_expose = array_filter($jmespath_result_to_expose); + $values = array_map('trim', $jmespath_result_to_expose); + $values = array_map('stripslashes', $values); + if ($is_date) { + $values_parsed = []; + $parser = EdtfFactory::newParser(); + foreach ($values as $value) { + $result = $parser->parse($value); + if ($result->isValid()) { + $date_ini = $result->getEdtfValue()->getMin(); + $date_max = $result->getEdtfValue()->getMax(); + $date_ini = date('c', $date_ini); + $date_max = date('c', $date_max); + $values_parsed[] = $date_ini; + $values_parsed[] = $date_max; } } - // This is an array, don't double nest to make the normalizer happy. - $values = array_map('trim', $jmespath_result_to_expose); - $values = array_map('stripslashes', $values); - - $this->processed = array_values($values); + $values = array_unique($values_parsed); + } + $this->processed = array_filter(array_values($values)); + $this->list = []; foreach ($this->processed as $delta => $item) { $this->list[$delta] = $this->createItem($delta, $item); } } else { $this->processed = []; + $this->list = []; } $this->computed = TRUE; } @@ -126,7 +143,7 @@ public function get($index) { throw new \InvalidArgumentException('Unable to get a value with a non-numeric delta in a list.'); } $this->ensureComputedValue(); - return isset($this->list[$index]) ? $this->list[$index] : NULL; + return !empty($this->list[$index]) ? $this->list[$index] : NULL; } /** * {@inheritdoc} diff --git a/src/Plugin/Field/FieldType/StrawberryFieldItem.php b/src/Plugin/Field/FieldType/StrawberryFieldItem.php index 20920d2..1220f13 100644 --- a/src/Plugin/Field/FieldType/StrawberryFieldItem.php +++ b/src/Plugin/Field/FieldType/StrawberryFieldItem.php @@ -181,6 +181,7 @@ public static function propertyDefinitions(FieldStorageDefinitionInterface $fiel ->setReadOnly(TRUE); } else { + $is_date = $plugin_config_entity_configs[$processor_class][$property]['is_date'] ?? FALSE; $properties[$property] = ListDataDefinition::create( $item_types[$processor_class] ) @@ -189,6 +190,7 @@ public static function propertyDefinitions(FieldStorageDefinitionInterface $fiel ->setClass($processor_class) ->setInternal(TRUE) ->setSetting('jsonkey', $keyname) + ->setSetting('is_date', $is_date) ->setReadOnly(TRUE); } } @@ -324,7 +326,7 @@ public function searchPath($expression, $force = TRUE) { else { if ($this->jsonjmesresults == NULL || !isset($this->jsonjmesresults[$expression]) || $force) { $mainproperty = $this->mainPropertyName(); - $jsonArray = json_decode($this->{$mainproperty}, TRUE, 50); + $jsonArray = json_decode($this->{$mainproperty}, TRUE, 64); $searchresult = StrawberryfieldJsonHelper::searchJson($expression, $jsonArray); $this->jsonjmesresults[$expression] = $searchresult; return $searchresult; diff --git a/src/Plugin/StrawberryfieldKeyNameProvider/JmesPathNameProvider.php b/src/Plugin/StrawberryfieldKeyNameProvider/JmesPathNameProvider.php index 76322eb..c888735 100644 --- a/src/Plugin/StrawberryfieldKeyNameProvider/JmesPathNameProvider.php +++ b/src/Plugin/StrawberryfieldKeyNameProvider/JmesPathNameProvider.php @@ -48,6 +48,7 @@ public function defaultConfiguration() { 'source_key' => '', // Example hocr 'exposed_key' => '', + 'is_date' => FALSE, // The id of the config entity from where these values came from.' 'configEntity' => NULL ] + parent::defaultConfiguration(); @@ -69,6 +70,15 @@ public function settingsForm(array $parents, FormStateInterface $form_state) { '#description' => $this->t('JMespath(s) will be evaluated against your Strawberry field JSON to extract data.
e.g. subject_loc[*].label'), '#required' => true, ]; + + $element['is_date'] = [ + '#id' => 'is_date', + '#type' => 'checkbox', + '#title' => $this->t('Is Date?'), + '#default_value' => $this->getConfiguration()['is_date'], + '#description' => $this->t('If checked the value coming from your Strawberry field JSON will be validated to be a Date.'), + '#required' => FALSE, + ]; // We need the parent form structure, if any, to make machine name work. $exposed_key_parents = $parents; $exposed_key_parents[] = 'source_key'; diff --git a/src/Tools/StrawberryfieldJsonHelper.php b/src/Tools/StrawberryfieldJsonHelper.php index bfabb45..c546079 100644 --- a/src/Tools/StrawberryfieldJsonHelper.php +++ b/src/Tools/StrawberryfieldJsonHelper.php @@ -351,8 +351,6 @@ public static function arrayIsMultiIterative(array $sourcearray = []) { return false; } - - /** * * @@ -363,9 +361,30 @@ public static function arrayIsMultiIterative(array $sourcearray = []) { * @return mixed|null Returns the matching data or null */ public static function searchJson($expression, array $sourcearray = []) { - return JmesPath::search($expression, $sourcearray); + if (!static::jmesPathIsKey($expression)){ + return JmesPath::search($expression, $sourcearray); + } + else { + $key = trim($expression,'"'); + return $sourcearray[$key] ?? NULL; + } } + /** + * Checks if a JMESPath expression is an array key in disguise. + * @param $expression + * + * @return bool + */ + public static function jmesPathIsKey($expression) { + $expression = trim($expression, '"'); + if (preg_match("/(\[|\.|\*)/", $expression)) { + return FALSE; + } + else { + return TRUE; + } + } /** * Takes an array and generates a JMESPath Filter expression