Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save junaidpv/d74b3abb5563b289c715771fc3accd11 to your computer and use it in GitHub Desktop.
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.
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