X-Git-Url: http://www.aleph1.co.uk/gitweb/?a=blobdiff_plain;f=web%2Fcore%2Fmodules%2Fviews%2Fsrc%2FPlugin%2Fviews%2Ffilter%2FBooleanOperator.php;fp=web%2Fcore%2Fmodules%2Fviews%2Fsrc%2FPlugin%2Fviews%2Ffilter%2FBooleanOperator.php;h=917a30b848cb098ed09b958dc93a974322094f95;hb=a2bd1bf0c2c1f1a17d188f4dc0726a45494cefae;hp=0000000000000000000000000000000000000000;hpb=57c063afa3f66b07c4bbddc2d6129a96d90f0aad;p=yaffs-website diff --git a/web/core/modules/views/src/Plugin/views/filter/BooleanOperator.php b/web/core/modules/views/src/Plugin/views/filter/BooleanOperator.php new file mode 100644 index 000000000..917a30b84 --- /dev/null +++ b/web/core/modules/views/src/Plugin/views/filter/BooleanOperator.php @@ -0,0 +1,273 @@ + 0. + * This might be helpful for performance reasons. + * + * @ingroup views_filter_handlers + * + * @ViewsFilter("boolean") + */ +class BooleanOperator extends FilterPluginBase { + + /** + * The equal query operator. + * + * @var string + */ + const EQUAL = '='; + + /** + * The non equal query operator. + * + * @var string + */ + const NOT_EQUAL = '<>'; + + // exposed filter options + protected $alwaysMultiple = TRUE; + // Don't display empty space where the operator would be. + public $no_operator = TRUE; + // Whether to accept NULL as a false value or not + public $accept_null = FALSE; + + + + /** + * {@inheritdoc} + */ + public function operatorOptions($which = 'title') { + $options = []; + foreach ($this->operators() as $id => $info) { + $options[$id] = $info[$which]; + } + + return $options; + } + + /** + * Returns an array of operator information. + * + * @return array + */ + protected function operators() { + return [ + '=' => [ + 'title' => $this->t('Is equal to'), + 'method' => 'queryOpBoolean', + 'short' => $this->t('='), + 'values' => 1, + 'query_operator' => self::EQUAL, + ], + '!=' => [ + 'title' => $this->t('Is not equal to'), + 'method' => 'queryOpBoolean', + 'short' => $this->t('!='), + 'values' => 1, + 'query_operator' => self::NOT_EQUAL, + ], + ]; + } + + /** + * {@inheritdoc} + */ + public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) { + parent::init($view, $display, $options); + + $this->value_value = $this->t('True'); + + if (isset($this->definition['label'])) { + $this->value_value = $this->definition['label']; + } + elseif (isset($this->definition['title'])) { + $this->value_value = $this->definition['title']; + } + + if (isset($this->definition['accept null'])) { + $this->accept_null = (bool) $this->definition['accept null']; + } + elseif (isset($this->definition['accept_null'])) { + $this->accept_null = (bool) $this->definition['accept_null']; + } + $this->valueOptions = NULL; + } + + /** + * Return the possible options for this filter. + * + * Child classes should override this function to set the possible values + * for the filter. Since this is a boolean filter, the array should have + * two possible keys: 1 for "True" and 0 for "False", although the labels + * can be whatever makes sense for the filter. These values are used for + * configuring the filter, when the filter is exposed, and in the admin + * summary of the filter. Normally, this should be static data, but if it's + * dynamic for some reason, child classes should use a guard to reduce + * database hits as much as possible. + */ + public function getValueOptions() { + if (isset($this->definition['type'])) { + if ($this->definition['type'] == 'yes-no') { + $this->valueOptions = [1 => $this->t('Yes'), 0 => $this->t('No')]; + } + if ($this->definition['type'] == 'on-off') { + $this->valueOptions = [1 => $this->t('On'), 0 => $this->t('Off')]; + } + if ($this->definition['type'] == 'enabled-disabled') { + $this->valueOptions = [1 => $this->t('Enabled'), 0 => $this->t('Disabled')]; + } + } + + // Provide a fallback if the above didn't set anything. + if (!isset($this->valueOptions)) { + $this->valueOptions = [1 => $this->t('True'), 0 => $this->t('False')]; + } + } + + protected function defineOptions() { + $options = parent::defineOptions(); + + $options['value']['default'] = FALSE; + + return $options; + } + + protected function valueForm(&$form, FormStateInterface $form_state) { + if (empty($this->valueOptions)) { + // Initialize the array of possible values for this filter. + $this->getValueOptions(); + } + if ($exposed = $form_state->get('exposed')) { + // Exposed filter: use a select box to save space. + $filter_form_type = 'select'; + } + else { + // Configuring a filter: use radios for clarity. + $filter_form_type = 'radios'; + } + $form['value'] = [ + '#type' => $filter_form_type, + '#title' => $this->value_value, + '#options' => $this->valueOptions, + '#default_value' => $this->value, + ]; + if (!empty($this->options['exposed'])) { + $identifier = $this->options['expose']['identifier']; + $user_input = $form_state->getUserInput(); + if ($exposed && !isset($user_input[$identifier])) { + $user_input[$identifier] = $this->value; + $form_state->setUserInput($user_input); + } + // If we're configuring an exposed filter, add an - Any - option. + if (!$exposed || empty($this->options['expose']['required'])) { + $form['value']['#options'] = ['All' => $this->t('- Any -')] + $form['value']['#options']; + } + } + } + + protected function valueValidate($form, FormStateInterface $form_state) { + if ($form_state->getValue(['options', 'value']) == 'All' && !$form_state->isValueEmpty(['options', 'expose', 'required'])) { + $form_state->setErrorByName('value', $this->t('You must select a value unless this is an non-required exposed filter.')); + } + } + + public function adminSummary() { + if ($this->isAGroup()) { + return $this->t('grouped'); + } + if (!empty($this->options['exposed'])) { + return $this->t('exposed'); + } + if (empty($this->valueOptions)) { + $this->getValueOptions(); + } + // Now that we have the valid options for this filter, just return the + // human-readable label based on the current value. The valueOptions + // array is keyed with either 0 or 1, so if the current value is not + // empty, use the label for 1, and if it's empty, use the label for 0. + return $this->operator . ' ' . $this->valueOptions[!empty($this->value)]; + } + + public function defaultExposeOptions() { + parent::defaultExposeOptions(); + $this->options['expose']['operator_id'] = ''; + $this->options['expose']['label'] = $this->value_value; + $this->options['expose']['required'] = TRUE; + } + + /** + * {@inheritdoc} + */ + public function query() { + $this->ensureMyTable(); + $field = "$this->tableAlias.$this->realField"; + + $info = $this->operators(); + if (!empty($info[$this->operator]['method'])) { + call_user_func([$this, $info[$this->operator]['method']], $field, $info[$this->operator]['query_operator']); + } + } + + /** + * Adds a where condition to the query for a boolean value. + * + * @param string $field + * The field name to add the where condition for. + * @param string $query_operator + * (optional) Either self::EQUAL or self::NOT_EQUAL. Defaults to + * self::EQUAL. + */ + protected function queryOpBoolean($field, $query_operator = self::EQUAL) { + if (empty($this->value)) { + if ($this->accept_null) { + if ($query_operator === self::EQUAL) { + $condition = (new Condition('OR')) + ->condition($field, 0, $query_operator) + ->isNull($field); + } + else { + $condition = (new Condition('AND')) + ->condition($field, 0, $query_operator) + ->isNotNull($field); + } + $this->query->addWhere($this->options['group'], $condition); + } + else { + $this->query->addWhere($this->options['group'], $field, 0, $query_operator); + } + } + else { + if (!empty($this->definition['use_equal'])) { + // Forces a self::EQUAL operator instead of a self::NOT_EQUAL for + // performance reasons. + if ($query_operator === self::EQUAL) { + $this->query->addWhere($this->options['group'], $field, 1, self::EQUAL); + } + else { + $this->query->addWhere($this->options['group'], $field, 0, self::EQUAL); + } + } + else { + $this->query->addWhere($this->options['group'], $field, 1, $query_operator); + } + } + } + +}