Created
December 5, 2023 17:42
-
-
Save junaidpv/d74b3abb5563b289c715771fc3accd11 to your computer and use it in GitHub Desktop.
It is exactly same patch as https://www.drupal.org/project/drupal/issues/2982968#comment-15346850 but mofied date format to use Americal style.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/core/modules/datetime/src/Plugin/views/filter/Date.php b/core/modules/datetime/src/Plugin/views/filter/Date.php | |
index f73a675fef..a303e3060f 100644 | |
--- a/core/modules/datetime/src/Plugin/views/filter/Date.php | |
+++ b/core/modules/datetime/src/Plugin/views/filter/Date.php | |
@@ -109,6 +109,11 @@ protected function opBetween($field) { | |
// value as UNIX timestamp 0. | |
$min = (!empty($this->value['min'])) ? $this->value['min'] : '@0'; | |
+ if (!empty($this->value['max']) && !strpos($this->value['max'], ':')) { | |
+ // No time was specified, so make the date range inclusive. | |
+ $this->value['max'] .= ' +1 day'; | |
+ } | |
+ | |
// Convert to ISO format and format for query. UTC timezone is used since | |
// dates are stored in UTC. | |
$a = new DateTimePlus($min, new \DateTimeZone($timezone)); | |
diff --git a/core/modules/views/src/Plugin/views/filter/Date.php b/core/modules/views/src/Plugin/views/filter/Date.php | |
index e15f0b2493..37a783178d 100644 | |
--- a/core/modules/views/src/Plugin/views/filter/Date.php | |
+++ b/core/modules/views/src/Plugin/views/filter/Date.php | |
@@ -13,37 +13,52 @@ | |
*/ | |
class Date extends NumericFilter { | |
- protected function defineOptions() { | |
- $options = parent::defineOptions(); | |
- | |
- // value is already set up properly, we're just adding our new field to it. | |
- $options['value']['contains']['type']['default'] = 'date'; | |
- | |
- return $options; | |
- } | |
- | |
/** | |
- * Add a type selector to the value form. | |
+ * {@inheritdoc} | |
*/ | |
protected function valueForm(&$form, FormStateInterface $form_state) { | |
+ parent::valueForm($form, $form_state); | |
+ | |
if (!$form_state->get('exposed')) { | |
- $form['value']['type'] = [ | |
- '#type' => 'radios', | |
- '#title' => $this->t('Value type'), | |
- '#options' => [ | |
- 'date' => $this->t('A date in any machine readable format. CCYY-MM-DD HH:MM:SS is preferred.'), | |
- 'offset' => $this->t('An offset from the current time such as "@example1" or "@example2"', ['@example1' => '+1 day', '@example2' => '-2 hours -30 minutes']), | |
- ], | |
- '#default_value' => !empty($this->value['type']) ? $this->value['type'] : 'date', | |
- ]; | |
+ // Use default values from options on the config form. | |
+ foreach (['min', 'max', 'value'] as $component) { | |
+ if (isset($this->options['value'][$component]) && isset($form['value'][$component])) { | |
+ $form['value'][$component]['#default_value'] = $this->options['value'][$component]; | |
+ | |
+ // Add description. | |
+ $form['value'][$component]['#description'] = $this->t('A date in any machine readable format (CCYY-MM-DD is preferred) or an offset from the current time such as "@example1" or "@example2".', [ | |
+ '@example1' => '+1 day', | |
+ '@example2' => '-2 years -10 days', | |
+ ]); | |
+ } | |
+ } | |
+ } | |
+ else { | |
+ // Convert relative date string representations to actual dates | |
+ // to solve potential datepicker problems. | |
+ foreach (['min', 'max', 'value'] as $component) { | |
+ if ( | |
+ isset($form['value'][$component]) && | |
+ !empty($form['value'][$component]['#default_value']) && | |
+ preg_match('/[a-zA-Z]+/', $form['value'][$component]['#default_value']) | |
+ ) { | |
+ $form['value'][$component]['#default_value'] = date('m/d/Y', strtotime($form['value'][$component]['#default_value'])); | |
+ } | |
+ } | |
} | |
- parent::valueForm($form, $form_state); | |
} | |
+ /** | |
+ * {@inheritdoc} | |
+ */ | |
public function validateOptionsForm(&$form, FormStateInterface $form_state) { | |
parent::validateOptionsForm($form, $form_state); | |
- if (!empty($this->options['exposed']) && $form_state->isValueEmpty(['options', 'expose', 'required'])) { | |
+ if (!empty($this->options['exposed']) && $form_state->isValueEmpty([ | |
+ 'options', | |
+ 'expose', | |
+ 'required', | |
+ ])) { | |
// Who cares what the value is if it's exposed and non-required. | |
return; | |
} | |
@@ -51,6 +66,9 @@ public function validateOptionsForm(&$form, FormStateInterface $form_state) { | |
$this->validateValidTime($form['value'], $form_state, $form_state->getValue(['options', 'operator']), $form_state->getValue(['options', 'value'])); | |
} | |
+ /** | |
+ * {@inheritdoc} | |
+ */ | |
public function validateExposed(&$form, FormStateInterface $form_state) { | |
if (empty($this->options['exposed'])) { | |
return; | |
@@ -105,39 +123,23 @@ protected function hasValidGroupedValue(array $group) { | |
return FALSE; | |
} | |
- // Special case when validating grouped date filters because the | |
- // $group['value'] array contains the type of filter (date or offset) and | |
- // therefore the number of items the comparison has to be done against is | |
- // one greater. | |
$operators = $this->operators(); | |
- $expected = $operators[$group['operator']]['values'] + 1; | |
+ $expected = $operators[$group['operator']]['values']; | |
$actual = count(array_filter($group['value'], [static::class, 'arrayFilterZero'])); | |
return $actual == $expected; | |
} | |
+ /** | |
+ * {@inheritdoc} | |
+ */ | |
public function acceptExposedInput($input) { | |
if (empty($this->options['exposed'])) { | |
return TRUE; | |
} | |
- // Store this because it will get overwritten. | |
- $type = NULL; | |
- if ($this->isAGroup()) { | |
- if (is_array($this->group_info)) { | |
- $type = $this->group_info['type']; | |
- } | |
- } | |
- else { | |
- $type = $this->value['type']; | |
- } | |
$rc = parent::acceptExposedInput($input); | |
- // Restore what got overwritten by the parent. | |
- if (!is_null($type)) { | |
- $this->value['type'] = $type; | |
- } | |
- | |
// Don't filter if value(s) are empty. | |
$operators = $this->operators(); | |
if (!empty($this->options['expose']['use_operator']) && !empty($this->options['expose']['operator_id'])) { | |
@@ -156,8 +158,8 @@ public function acceptExposedInput($input) { | |
} | |
elseif ($operators[$operator]['values'] == 2) { | |
// When the operator is either between or not between the input contains | |
- // two values. | |
- if ($this->value['min'] == '' || $this->value['max'] == '') { | |
+ // at least one value. | |
+ if ($this->value['min'] == '' && $this->value['max'] == '') { | |
return FALSE; | |
} | |
} | |
@@ -165,31 +167,57 @@ public function acceptExposedInput($input) { | |
return $rc; | |
} | |
+ /** | |
+ * Helper function to get converted values for the query. | |
+ * | |
+ * @return array | |
+ * Array of timestamps. | |
+ */ | |
+ protected function getConvertedValues() { | |
+ $values = []; | |
+ if (!empty($this->value['max']) && !strpos($this->value['max'], ':')) { | |
+ // No time was specified, so make the date range inclusive. | |
+ $this->value['max'] .= ' +1 day'; | |
+ } | |
+ foreach (['min', 'max', 'value'] as $component) { | |
+ if (!empty($this->value[$component])) { | |
+ $values[$component] = intval(strtotime($this->value[$component])); | |
+ } | |
+ } | |
+ return $values; | |
+ } | |
+ | |
+ /** | |
+ * {@inheritdoc} | |
+ */ | |
protected function opBetween($field) { | |
- $a = intval(strtotime($this->value['min'], 0)); | |
- $b = intval(strtotime($this->value['max'], 0)); | |
- | |
- if ($this->value['type'] == 'offset') { | |
- // Keep sign. | |
- $a = '***CURRENT_TIME***' . sprintf('%+d', $a); | |
- // Keep sign. | |
- $b = '***CURRENT_TIME***' . sprintf('%+d', $b); | |
- } | |
- // This is safe because we are manually scrubbing the values. | |
- // It is necessary to do it this way because $a and $b are formulas when using an offset. | |
- $operator = strtoupper($this->operator); | |
- $this->query->addWhereExpression($this->options['group'], "$field $operator $a AND $b"); | |
+ $values = $this->getConvertedValues(); | |
+ if (empty($values)) { | |
+ // do nothing | |
+ return; | |
+ } | |
+ // Support providing only one value for exposed filters. | |
+ if (empty($values['min'])) { | |
+ $operator = $this->operator === 'between' ? '<=' : '>'; | |
+ $this->query->addWhereExpression($this->options['group'], "$field $operator {$values['max']}"); | |
+ } | |
+ elseif (empty($values['max'])) { | |
+ $operator = $this->operator === 'between' ? '>=' : '<'; | |
+ $this->query->addWhereExpression($this->options['group'], "$field $operator {$values['min']}"); | |
+ } | |
+ // Both values given. | |
+ else { | |
+ $operator = strtoupper($this->operator); | |
+ $this->query->addWhereExpression($this->options['group'], "$field $operator {$values['min']} AND {$values['max']}"); | |
+ } | |
} | |
+ /** | |
+ * {@inheritdoc} | |
+ */ | |
protected function opSimple($field) { | |
- $value = intval(strtotime($this->value['value'], 0)); | |
- if (!empty($this->value['type']) && $this->value['type'] == 'offset') { | |
- // Keep sign. | |
- $value = '***CURRENT_TIME***' . sprintf('%+d', $value); | |
- } | |
- // This is safe because we are manually scrubbing the value. | |
- // It is necessary to do it this way because $value is a formula when using an offset. | |
- $this->query->addWhereExpression($this->options['group'], "$field $this->operator $value"); | |
+ $values = $this->getConvertedValues(); | |
+ $this->query->addWhereExpression($this->options['group'], "$field $this->operator {$values['value']}"); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment