- Issue created by @tobiberlin
- ๐ฉ๐ชGermany tobiberlin Berlin, Germany
It seems to me that
Date->validateValidTime()
is only fitting for calls coming fromvalidateOptionsForm()
- and it was re-used forvalidateExposed()
but without realizing that$this->options['expose']['identifier']
has another structure then. For me it's not clear what is going on here - but I think that validateValidTime() will never really work when a validation is done for exposed filter input - which apparently is only done when the field is required. - ๐ฉ๐ชGermany tobiberlin Berlin, Germany
I just solved it now the following way for my custom filter plugin:
public function validateExposed(&$form, FormStateInterface $form_state) { if (empty($this->options['exposed'])) { return; } $value = &$form_state->getValue($this->options['expose']['identifier']); if (!empty($this->options['expose']['use_operator']) && !empty($this->options['expose']['operator_id'])) { $operator = &$form_state->getValue($this->options['expose']['operator_id']); } else { $operator = $this->operator; } $this->validateExposedValidTime($this->options['expose']['identifier'], $form_state, $operator, $value); }
Changes: no stop of validation just because the field is not required, Replaced validateValidTime method call to call my custom validation method.
The method looks like this. The first parameter in this case is a string and instead of calling $form_state->setError() in case of a fals value I use $form_state->setErrorByName():
protected function validateExposedValidTime(string $elementIdentifier, FormStateInterface $form_state, string $operator, array $value) { $operators = $this->operators(); if ($operators[$operator]['values'] == 1) { $convert = strtotime($value['value']); if (!empty($elementIdentifier['value']) && ($convert == -1 || $convert === FALSE)) { $form_state->setErrorByName($elementIdentifier, $this->t('Invalid date format.')); } } elseif ($operators[$operator]['values'] == 2) { if (!empty($value['min'])) { $min = strtotime($value['min']); if ($min == -1 || $min === FALSE) { $form_state->setErrorByName($elementIdentifier, $this->t('Invalid date format.')); } } if (!empty($value['max'])) { $max = strtotime($value['max']); if ($max == -1 || $max === FALSE) { $form_state->setErrorByName($elementIdentifier, $this->t('Invalid date format.')); } } } }
As I am not sure what these changes may cause for other views filter plugin extending the Date class, for the options form and in the many other use cases I just adjusted it for our custom plugin as I can assure that it works how it should... but maybe this may help
- ๐ณ๐ฑNetherlands Lendude Amsterdam
Nice find. I agree validateExposed just seems like some copy/pasta of validateOptionsForm and in its current state will not work at all.
So a complete rewrite and some test coverage are probably in order.
- ๐จ๐ฆCanada dylan donkersgoed London, Ontario
dylan donkersgoed โ made their first commit to this issueโs fork.
- Merge request !9696Fixed validation for views date exposed form to run when not required,... โ (Open) created by dylan donkersgoed
- ๐จ๐ฆCanada dylan donkersgoed London, Ontario
I've added a patch for the actual Date filter plugin. I tried to transplant the code tobiberlin provided, but it resulted in fatal errors. The value is a string instead of an array unless it has multiple values, could be related to their custom plugin? The solution I've provided is pretty similar though.
This patch should probably have automated tests to go with it, so I'm marking it as Needs Work. But the patch seems to be working for me locally at least.
- ๐ฎ๐ณIndia KumudB Ahmedabad
in Drupal version 11.x , above patch is working as expected and there is no error in my local as well. here I attached screenshots as well.