Version 1
[yaffs-website] / web / core / modules / views / src / Plugin / views / filter / NumericFilter.php
diff --git a/web/core/modules/views/src/Plugin/views/filter/NumericFilter.php b/web/core/modules/views/src/Plugin/views/filter/NumericFilter.php
new file mode 100644 (file)
index 0000000..7f687a1
--- /dev/null
@@ -0,0 +1,342 @@
+<?php
+
+namespace Drupal\views\Plugin\views\filter;
+
+use Drupal\Core\Form\FormStateInterface;
+
+/**
+ * Simple filter to handle greater than/less than filters
+ *
+ * @ingroup views_filter_handlers
+ *
+ * @ViewsFilter("numeric")
+ */
+class NumericFilter extends FilterPluginBase {
+
+  protected $alwaysMultiple = TRUE;
+
+  protected function defineOptions() {
+    $options = parent::defineOptions();
+
+    $options['value'] = [
+      'contains' => [
+        'min' => ['default' => ''],
+        'max' => ['default' => ''],
+        'value' => ['default' => ''],
+      ],
+    ];
+
+    return $options;
+  }
+
+  public function operators() {
+    $operators = [
+      '<' => [
+        'title' => $this->t('Is less than'),
+        'method' => 'opSimple',
+        'short' => $this->t('<'),
+        'values' => 1,
+      ],
+      '<=' => [
+        'title' => $this->t('Is less than or equal to'),
+        'method' => 'opSimple',
+        'short' => $this->t('<='),
+        'values' => 1,
+      ],
+      '=' => [
+        'title' => $this->t('Is equal to'),
+        'method' => 'opSimple',
+        'short' => $this->t('='),
+        'values' => 1,
+      ],
+      '!=' => [
+        'title' => $this->t('Is not equal to'),
+        'method' => 'opSimple',
+        'short' => $this->t('!='),
+        'values' => 1,
+      ],
+      '>=' => [
+        'title' => $this->t('Is greater than or equal to'),
+        'method' => 'opSimple',
+        'short' => $this->t('>='),
+        'values' => 1,
+      ],
+      '>' => [
+        'title' => $this->t('Is greater than'),
+        'method' => 'opSimple',
+        'short' => $this->t('>'),
+        'values' => 1,
+      ],
+      'between' => [
+        'title' => $this->t('Is between'),
+        'method' => 'opBetween',
+        'short' => $this->t('between'),
+        'values' => 2,
+      ],
+      'not between' => [
+        'title' => $this->t('Is not between'),
+        'method' => 'opBetween',
+        'short' => $this->t('not between'),
+        'values' => 2,
+      ],
+      'regular_expression' => [
+        'title' => $this->t('Regular expression'),
+        'short' => $this->t('regex'),
+        'method' => 'opRegex',
+        'values' => 1,
+      ],
+    ];
+
+    // if the definition allows for the empty operator, add it.
+    if (!empty($this->definition['allow empty'])) {
+      $operators += [
+        'empty' => [
+          'title' => $this->t('Is empty (NULL)'),
+          'method' => 'opEmpty',
+          'short' => $this->t('empty'),
+          'values' => 0,
+        ],
+        'not empty' => [
+          'title' => $this->t('Is not empty (NOT NULL)'),
+          'method' => 'opEmpty',
+          'short' => $this->t('not empty'),
+          'values' => 0,
+        ],
+      ];
+    }
+
+    return $operators;
+  }
+
+  /**
+   * Provide a list of all the numeric operators
+   */
+  public function operatorOptions($which = 'title') {
+    $options = [];
+    foreach ($this->operators() as $id => $info) {
+      $options[$id] = $info[$which];
+    }
+
+    return $options;
+  }
+
+  protected function operatorValues($values = 1) {
+    $options = [];
+    foreach ($this->operators() as $id => $info) {
+      if ($info['values'] == $values) {
+        $options[] = $id;
+      }
+    }
+
+    return $options;
+  }
+  /**
+   * Provide a simple textfield for equality
+   */
+  protected function valueForm(&$form, FormStateInterface $form_state) {
+    $form['value']['#tree'] = TRUE;
+
+    // We have to make some choices when creating this as an exposed
+    // filter form. For example, if the operator is locked and thus
+    // not rendered, we can't render dependencies; instead we only
+    // render the form items we need.
+    $which = 'all';
+    if (!empty($form['operator'])) {
+      $source = ':input[name="options[operator]"]';
+    }
+
+    if ($exposed = $form_state->get('exposed')) {
+      $identifier = $this->options['expose']['identifier'];
+
+      if (empty($this->options['expose']['use_operator']) || empty($this->options['expose']['operator_id'])) {
+        // exposed and locked.
+        $which = in_array($this->operator, $this->operatorValues(2)) ? 'minmax' : 'value';
+      }
+      else {
+        $source = ':input[name="' . $this->options['expose']['operator_id'] . '"]';
+      }
+    }
+
+    $user_input = $form_state->getUserInput();
+    if ($which == 'all') {
+      $form['value']['value'] = [
+        '#type' => 'textfield',
+        '#title' => !$exposed ? $this->t('Value') : '',
+        '#size' => 30,
+        '#default_value' => $this->value['value'],
+      ];
+      // Setup #states for all operators with one value.
+      foreach ($this->operatorValues(1) as $operator) {
+        $form['value']['value']['#states']['visible'][] = [
+          $source => ['value' => $operator],
+        ];
+      }
+      if ($exposed && !isset($user_input[$identifier]['value'])) {
+        $user_input[$identifier]['value'] = $this->value['value'];
+        $form_state->setUserInput($user_input);
+      }
+    }
+    elseif ($which == 'value') {
+      // When exposed we drop the value-value and just do value if
+      // the operator is locked.
+      $form['value'] = [
+        '#type' => 'textfield',
+        '#title' => !$exposed ? $this->t('Value') : '',
+        '#size' => 30,
+        '#default_value' => $this->value['value'],
+      ];
+      if ($exposed && !isset($user_input[$identifier])) {
+        $user_input[$identifier] = $this->value['value'];
+        $form_state->setUserInput($user_input);
+      }
+    }
+
+    if ($which == 'all' || $which == 'minmax') {
+      $form['value']['min'] = [
+        '#type' => 'textfield',
+        '#title' => !$exposed ? $this->t('Min') : $this->exposedInfo()['label'],
+        '#size' => 30,
+        '#default_value' => $this->value['min'],
+        '#description' => !$exposed ? '' : $this->exposedInfo()['description']
+      ];
+      $form['value']['max'] = [
+        '#type' => 'textfield',
+        '#title' => !$exposed ? $this->t('And max') : $this->t('And'),
+        '#size' => 30,
+        '#default_value' => $this->value['max'],
+      ];
+      if ($which == 'all') {
+        $states = [];
+        // Setup #states for all operators with two values.
+        foreach ($this->operatorValues(2) as $operator) {
+          $states['#states']['visible'][] = [
+            $source => ['value' => $operator],
+          ];
+        }
+        $form['value']['min'] += $states;
+        $form['value']['max'] += $states;
+      }
+      if ($exposed && !isset($user_input[$identifier]['min'])) {
+        $user_input[$identifier]['min'] = $this->value['min'];
+      }
+      if ($exposed && !isset($user_input[$identifier]['max'])) {
+        $user_input[$identifier]['max'] = $this->value['max'];
+      }
+
+      if (!isset($form['value'])) {
+        // Ensure there is something in the 'value'.
+        $form['value'] = [
+          '#type' => 'value',
+          '#value' => NULL
+        ];
+      }
+    }
+  }
+
+  public function query() {
+    $this->ensureMyTable();
+    $field = "$this->tableAlias.$this->realField";
+
+    $info = $this->operators();
+    if (!empty($info[$this->operator]['method'])) {
+      $this->{$info[$this->operator]['method']}($field);
+    }
+  }
+
+  protected function opBetween($field) {
+    if ($this->operator == 'between') {
+      $this->query->addWhere($this->options['group'], $field, [$this->value['min'], $this->value['max']], 'BETWEEN');
+    }
+    else {
+      $this->query->addWhere($this->options['group'], $field, [$this->value['min'], $this->value['max']], 'NOT BETWEEN');
+    }
+  }
+
+  protected function opSimple($field) {
+    $this->query->addWhere($this->options['group'], $field, $this->value['value'], $this->operator);
+  }
+
+  protected function opEmpty($field) {
+    if ($this->operator == 'empty') {
+      $operator = "IS NULL";
+    }
+    else {
+      $operator = "IS NOT NULL";
+    }
+
+    $this->query->addWhere($this->options['group'], $field, NULL, $operator);
+  }
+
+  /**
+   * Filters by a regular expression.
+   *
+   * @param string $field
+   *   The expression pointing to the queries field, for example "foo.bar".
+   */
+  protected function opRegex($field) {
+    $this->query->addWhere($this->options['group'], $field, $this->value['value'], 'REGEXP');
+  }
+
+  public function adminSummary() {
+    if ($this->isAGroup()) {
+      return $this->t('grouped');
+    }
+    if (!empty($this->options['exposed'])) {
+      return $this->t('exposed');
+    }
+
+    $options = $this->operatorOptions('short');
+    $output = $options[$this->operator];
+    if (in_array($this->operator, $this->operatorValues(2))) {
+      $output .= ' ' . $this->t('@min and @max', ['@min' => $this->value['min'], '@max' => $this->value['max']]);
+    }
+    elseif (in_array($this->operator, $this->operatorValues(1))) {
+      $output .= ' ' . $this->value['value'];
+    }
+    return $output;
+  }
+
+  /**
+   * Do some minor translation of the exposed input
+   */
+  public function acceptExposedInput($input) {
+    if (empty($this->options['exposed'])) {
+      return TRUE;
+    }
+
+    // rewrite the input value so that it's in the correct format so that
+    // the parent gets the right data.
+    if (!empty($this->options['expose']['identifier'])) {
+      $value = &$input[$this->options['expose']['identifier']];
+      if (!is_array($value)) {
+        $value = [
+          'value' => $value,
+        ];
+      }
+    }
+
+    $rc = parent::acceptExposedInput($input);
+
+    if (empty($this->options['expose']['required'])) {
+      // We have to do some of our own checking for non-required filters.
+      $info = $this->operators();
+      if (!empty($info[$this->operator]['values'])) {
+        switch ($info[$this->operator]['values']) {
+          case 1:
+            if ($value['value'] === '') {
+              return FALSE;
+            }
+            break;
+          case 2:
+            if ($value['min'] === '' && $value['max'] === '') {
+              return FALSE;
+            }
+            break;
+        }
+      }
+    }
+
+    return $rc;
+  }
+
+}