Skip to content

Commit a149a64

Browse files
committed
It's working!
1 parent f677935 commit a149a64

File tree

1 file changed

+62
-120
lines changed

1 file changed

+62
-120
lines changed

src/Plugin/views/filter/Selective.php

Lines changed: 62 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,11 @@
77

88
namespace Drupal\views_selective_filters\Plugin\views\filter;
99

10+
use Drupal\Component\Utility\SafeMarkup;
1011
use Drupal\Core\Form\FormStateInterface;
12+
use Drupal\views\Plugin\views\display\DisplayPluginBase;
1113
use Drupal\views\Plugin\views\filter\InOperator;
14+
use Drupal\views\ViewExecutable;
1215
use Drupal\views\Views;
1316

1417
/**
@@ -29,6 +32,15 @@ class Selective extends InOperator {
2932

3033
protected static $results;
3134

35+
/**
36+
* {@inheritdoc}
37+
*/
38+
public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) {
39+
parent::init($view, $display, $options);
40+
41+
$this->options['exposed'] = TRUE;
42+
}
43+
3244
/**
3345
* {@inheritdoc}
3446
*/
@@ -62,7 +74,6 @@ public function getValueOptions() {
6274
// is to prevent infinite recursive loop.
6375
if (empty($this->view->selective_oids) && !empty($this->view->inited)) {
6476
$this->valueOptions = $this->getOids();
65-
debug('called');
6677
// TODO: Omit null values in result: they are improperly handled.
6778
// When constructing the query.
6879
$this->valueOptions = array_diff_key($this->valueOptions, ['' => NULL]);
@@ -109,9 +120,8 @@ protected function valueForm(&$form, FormStateInterface $form_state) {
109120
/**
110121
* Checks if two base fields are compatible.
111122
*/
112-
protected function BaseFieldCompatible($base_field1, $base_field2) {
123+
protected function baseFieldCompatible($base_field1, $base_field2) {
113124
return strpos($base_field2, $base_field1) === 0;
114-
return preg_match('/^' . $base_field1 . '/', $base_field2);
115125
}
116126

117127
/**
@@ -124,29 +134,28 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) {
124134
// Filter should always be exposed, show warning.
125135
array_unshift($form['expose_button'], array(
126136
'warning' => array(
127-
'#type' => 'markup',
128-
'#markup' => '<div class="messages warning">' . t('This filter is always exposed to users.') . '</div>',
137+
'#theme' => 'status_messages',
138+
'#message_list' => ['warning' => [t('This filter is always exposed to users.')]],
139+
'#status_headings' => [
140+
'status' => t('Status message'),
141+
'error' => t('Error message'),
142+
'warning' => t('Warning message'),
143+
],
129144
)));
130145
// Remove option to unexpose filter. Tried to disable, but did not work.
131146
$form['expose_button']['checkbox']['checkbox']['#type'] = 'hidden';
132147
unset($form['expose_button']['button']);
133148
unset($form['expose_button']['markup']);
134149
// Do not allow to check "all values".
135-
$form['value']['#attributes']['disabled'] = 'disabled';
150+
$form['value']['#access'] = FALSE;
136151
// Cannot group without values.
137152
unset($form['group_button']);
138153

139-
// Preload handlers, sorts and filters.
140-
// This gest cached all along.
141-
$this->view->display_handler->getHandlers('field');
142-
$this->view->display_handler->getHandlers('sort');
143-
$this->view->display_handler->getHandlers('filter');
144-
145154
// Add combo to pick display field for filter.
146155
$options = [];
147-
foreach ($this->view->display_handler->handlers['field'] as $key => $handler) {
148-
if ($this->BaseFieldCompatible($base_field, $handler->field)) {
149-
$options[$handler->options['id']] = $handler->definition['group'] . ': ' . $handler->definition['title'] . '(' . $handler->label() . ')';
156+
foreach ($this->view->display_handler->getHandlers('field') as $field) {
157+
if ($this->baseFieldCompatible($base_field, $field->field)) {
158+
$options[$field->options['id']] = $field->adminLabel();
150159
}
151160
}
152161

@@ -218,13 +227,7 @@ public function query() {
218227
if (isset($this->view->selective_handler_signature) && $this->getSignature() === $this->view->selective_handler_signature) {
219228
return;
220229
}
221-
// Decode the values to restore special chars.
222-
if (is_array($this->value)) {
223-
$this->value = array_map('urldecode', $this->value);
224-
}
225-
elseif (is_string($this->value)){
226-
$this->value = urldecode($this->value);
227-
}
230+
228231
parent::query();
229232
}
230233

@@ -236,14 +239,14 @@ public function query() {
236239
*/
237240
protected function getSignature() {
238241
return hash('sha256', serialize(array(
239-
'name' => $this->view->name,
242+
'id' => $this->view->id(),
240243
'args' => $this->view->args,
241-
'input' => $this->view->exposed_input,
244+
'input' => $this->view->getExposedInput(),
242245
'base_field' => $this->definition['field_base'],
243-
'real_field' => $this->real_field,
246+
'real_field' => $this->realField,
244247
'field' => $this->field,
245248
'table' => $this->table,
246-
'ui_name' => $this->options['ui_name'],
249+
'ui_name' => $this->adminLabel(),
247250
)));
248251
}
249252

@@ -253,7 +256,7 @@ protected function getSignature() {
253256
protected function getOids() {
254257
// Parameters that we will be using during the process.
255258
$base_field = $this->definition['field_base'];
256-
$ui_name = $this->options['ui_name'];
259+
$ui_name = $this->adminLabel();
257260
$signature = $this->getSignature();
258261

259262
// Prevent same filters from being recalculated.
@@ -280,54 +283,18 @@ protected function getOids() {
280283
// Limit result set to 100: anything above is not user friendly at all.
281284
$view_copy->setItemsPerPage($max_items);
282285

283-
// Remove paging, and page number from context.
284-
if (isset($_GET['items_per_page'])) {
285-
$items_per_page = $_GET['items_per_page'];
286-
unset($_GET['items_per_page']);
287-
}
288-
if (isset($_GET['page'])) {
289-
$exposed_page = $_GET['page'];
290-
unset($_GET['page']);
291-
}
292-
293-
// Manipulate display + default: don't know if fields are overriden.
294-
$display = $view_copy->display[$this->view->current_display];
295-
$display_default = $view_copy->display['default'];
286+
$view_copy->setDisplay($this->view->current_display);
287+
$display = $view_copy->getDisplay();
296288

297289
// Remove any exposed form configuration. This showed up with BEF module!
298290
unset($display->display_options['exposed_form']);
299-
unset($display_default->display_options['exposed_form']);
300291

301-
// Also disable attachments.
302-
$display->handler->definition['accept attachments'] = FALSE;
303-
$display_default->handler->definition['accept attachments'] = FALSE;
292+
$fields =& $display->getHandlers('field');
304293

305-
// If we are using fields from default or current display.
306-
if (isset($display->display_options['fields'])) {
307-
$display_options_fields = &$display->display_options['fields'];
308-
}
309-
else {
310-
$display_options_fields = &$display_default->display_options['fields'];
311-
}
312-
313-
// Original implementation based field matching on ui_name matches
314-
// so we need to preserve backwards compatibility.
315-
$field_to_keep = $this->options['selective_display_field'];
316-
317-
// Remove all fields but the one used to display and aggregate.
318-
foreach ($display_options_fields as $key => $value) {
319-
if ($key !== $field_to_keep) {
320-
unset($display_options_fields[$key]);
321-
}
322-
else {
323-
// If there is a group column on the field, remove it so Field Collections will work.
324-
// https://www.drupal.org/node/2333065
325-
unset($display_options_fields[$key]['group_column']);
326-
}
327-
}
294+
$fields = array_intersect_key($fields, [$this->options['selective_display_field'] => TRUE]);
328295

329296
// Check to see if the user remembered to add the field.
330-
if (empty($display_options_fields)) {
297+
if (empty($fields)) {
331298
drupal_set_message(t('Selective query filter must have corresponding field added to view with Administrative Name set to "@name" and Base Type "@type"',
332299
array(
333300
'@name' => $ui_name,
@@ -337,17 +304,19 @@ protected function getOids() {
337304
}
338305

339306
// Get ID of field that will be used for rendering.
340-
$display_field = reset($display_options_fields);
307+
$field = reset($fields);
308+
309+
$field_options = $field->options;
341310

342311
// Get field Id.
343-
$display_field_id = $display_field['id'];
312+
$field_id = $field_options['id'];
344313

345314
// Check that relationships are coherent between Field and Filter.
346-
$no_display_field_relationship = empty($display_field['relationship']) || $display_field['relationship'] === 'none';
315+
$no_display_field_relationship = empty($field_options['relationship']) || $field_options['relationship'] === 'none';
347316
$no_filter_relationship = empty($this->options['relationship']) || $this->options['relationship'] === 'none';
348317
$equal
349318
= (($no_display_field_relationship === TRUE) && ($no_filter_relationship === TRUE)) ||
350-
($display_field['relationship'] === $this->options['relationship']);
319+
($field_options['relationship'] === $this->options['relationship']);
351320

352321
if (!$equal) {
353322
drupal_set_message(t('Selective filter "@name": relationship of field and filter must match.',
@@ -360,71 +329,43 @@ protected function getOids() {
360329

361330
// If main field is excluded from presentation, bring it back.
362331
// Set group type for handler to populate database relationships in query.
363-
$display_field['exclude'] = 0;
364-
$display_field['group_type'] = 'group';
332+
$field_options['exclude'] = 0;
333+
$field_options['group_type'] = 'group';
365334

366335
// Remove all sorting: sorts must be added to aggregate fields.
367-
unset($display->display_options['sorts']);
368-
unset($display_default->display_options['sorts']);
336+
// $sorts =& $display->getHandlers('sort');
337+
// $sorts = [];
369338

370339
// Turn this into an aggregate query.
371-
$display->display_options['group_by'] = 1;
372-
$display->handler->options['group_by'] = 1;
373-
374-
$display_default->display_options['group_by'] = 1;
375-
$display_default->handler->options['group_by'] = 1;
340+
$display->setOption('group_by', 1);
376341

377342
// Aggregate is incompatible with distinct and pure distinct.
378343
// At least it does not make sense as it is implemented now.
379-
unset($display_default->display_options['query']['options']['distinct']);
380-
unset($display_default->display_options['query']['options']['pure_distinct']);
381-
382-
unset($display->display_options['query']['options']['distinct']);
383-
unset($display->display_options['query']['options']['pure_distinct']);
344+
$query_options = $display->getOption('query');
345+
$query_options['options']['distinct'] = TRUE;
346+
$display->setOption('query', $query_options);
384347

385-
// Make sure we are not using a pager to prevent unnecessary count(*) queries.
386-
$display->display_options['pager'] = unserialize('a:2:{s:4:"type";s:4:"none";s:7:"options";a:1:{s:6:"offset";s:1:"0";}}');
387-
$display_default->display_options['pager'] = unserialize('a:2:{s:4:"type";s:4:"none";s:7:"options";a:1:{s:6:"offset";s:1:"0";}}');
388-
389-
// Some style plugins can affect the built query, make sure
390-
// we use a reliable field based style plugin.
391-
$display->display_options['style_plugin'] = 'default';
392-
$display->display_options['style_options'] = unserialize('a:4:{s:9:"row_class";s:0:"";s:17:"default_row_class";i:1;s:17:"row_class_special";i:1;s:11:"uses_fields";i:0;}');
393-
$display->display_options['row_plugin'] = 'fields';
394-
$display->display_options['row_options'] = unserialize('s:6:"fields";');
348+
// Some style plugins can affect the built query, make sure we use a
349+
// reliable field based style plugin.
350+
$display->setOption('pager', ['type' => 'none', 'options' => []]);
351+
$display->setOption('style', ['type' => 'default', 'options' => []]);
352+
$display->setOption('row', ['type' => 'fields', 'options' => []]);
395353

396354
// Run View.
397355
$view_copy->execute($this->view->current_display);
398356

399-
// Restore context parameters for real View.
400-
if (isset($items_per_page)) {
401-
$_GET['items_per_page'] = $items_per_page;
402-
}
403-
if (isset($exposed_page)) {
404-
$_GET['page'] = $exposed_page;
405-
}
406-
407-
// Get Handler after execution.
408-
$display_field_handler = $view_copy->field[$display_field_id];
409-
410357
// We show human-readable values when case.
411-
if (method_exists($display_field_handler, 'getValueOptions')) {
412-
$display_field_handler->getValueOptions();
358+
if (method_exists($field, 'getValueOptions')) {
359+
$field->getValueOptions();
413360
}
414361

415362
// Create array of objects for selector.
416363
$oids = [];
417-
$field_alias = isset($display_field_handler->aliases[$display_field_handler->real_field]) ? $display_field_handler->aliases[$display_field_handler->real_field] : $display_field_handler->table_alias . '_' . $display_field_handler->real_field;
418-
foreach ($view_copy->result as $index => $row) {
419-
// $key = $display_field_handler->get_value($row) should be more robust.
420-
// But values are sometimes nested arrays, and we need single values.
421-
// For the filters.
422-
$key = $display_field_handler->get_value($row);
423-
if (is_array($key)) {
424-
$key = $row->{$field_alias};
425-
}
426-
$value = strip_tags($view_copy->render_field($display_field_id, $index));
427-
$oids[$key] = empty($value) ? t('Empty (@key)', array('@key' => empty($key) ? json_encode($key) : $key)) : $value;
364+
foreach ($view_copy->result as $row) {
365+
$key = $field->getValue($row);
366+
$key = is_array($key) ? reset($key) : $key;
367+
// @todo This double escapes markup.
368+
$oids[$key] = SafeMarkup::checkPlain($field->render($row));
428369
}
429370

430371
// Sort values.
@@ -465,6 +406,7 @@ protected function getOids() {
465406
static::$results[$signature] = $oids;
466407
$view_copy->destroy();
467408
}
409+
468410
return static::$results[$signature];
469411
}
470412

0 commit comments

Comments
 (0)