3 namespace Drupal\views\Plugin\views\filter;
5 use Drupal\Core\Form\FormStateInterface;
6 use Drupal\views\ViewExecutable;
7 use Drupal\views\Plugin\views\display\DisplayPluginBase;
8 use Drupal\views\ManyToOneHelper;
11 * Complex filter to handle filtering for many to one relationships,
12 * such as terms (many terms per node) or roles (many roles per user).
14 * The construct method needs to be overridden to provide a list of options;
15 * alternately, the valueForm and adminSummary methods need to be overridden
16 * to provide something that isn't just a select list.
18 * @ingroup views_filter_handlers
20 * @ViewsFilter("many_to_one")
22 class ManyToOne extends InOperator {
25 * @var \Drupal\views\ManyToOneHelper
27 * Stores the Helper object which handles the many_to_one complexity.
29 public $helper = NULL;
34 public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) {
35 parent::init($view, $display, $options);
37 $this->helper = new ManyToOneHelper($this);
40 protected function defineOptions() {
41 $options = parent::defineOptions();
43 $options['operator']['default'] = 'or';
44 $options['value']['default'] = [];
46 if (isset($this->helper)) {
47 $this->helper->defineOptions($options);
50 $helper = new ManyToOneHelper($this);
51 $helper->defineOptions($options);
57 public function operators() {
60 'title' => $this->t('Is one of'),
61 'short' => $this->t('or'),
62 'short_single' => $this->t('='),
63 'method' => 'opHelper',
65 'ensure_my_table' => 'helper',
68 'title' => $this->t('Is all of'),
69 'short' => $this->t('and'),
70 'short_single' => $this->t('='),
71 'method' => 'opHelper',
73 'ensure_my_table' => 'helper',
76 'title' => $this->t('Is none of'),
77 'short' => $this->t('not'),
78 'short_single' => $this->t('<>'),
79 'method' => 'opHelper',
81 'ensure_my_table' => 'helper',
84 // if the definition allows for the empty operator, add it.
85 if (!empty($this->definition['allow empty'])) {
88 'title' => $this->t('Is empty (NULL)'),
89 'method' => 'opEmpty',
90 'short' => $this->t('empty'),
94 'title' => $this->t('Is not empty (NOT NULL)'),
95 'method' => 'opEmpty',
96 'short' => $this->t('not empty'),
105 protected $valueFormType = 'select';
106 protected function valueForm(&$form, FormStateInterface $form_state) {
107 parent::valueForm($form, $form_state);
109 if (!$form_state->get('exposed')) {
110 $this->helper->buildOptionsForm($form, $form_state);
115 * Override ensureMyTable so we can control how this joins in.
116 * The operator actually has influence over joining.
118 public function ensureMyTable() {
119 // Defer to helper if the operator specifies it.
120 $info = $this->operators();
121 if (isset($info[$this->operator]['ensure_my_table']) && $info[$this->operator]['ensure_my_table'] == 'helper') {
122 return $this->helper->ensureMyTable();
125 return parent::ensureMyTable();
128 protected function opHelper() {
129 if (empty($this->value)) {
132 // Form API returns unchecked options in the form of option_id => 0. This
133 // breaks the generated query for "is all of" filters so we remove them.
134 $this->value = array_filter($this->value, 'static::arrayFilterZero');
135 $this->helper->addFilter();