Pathologic was missing because of a .git folder inside.
[yaffs-website] / web / modules / contrib / ctools / modules / ctools_views / src / Plugin / Display / Block.php
1 <?php
2
3 namespace Drupal\ctools_views\Plugin\Display;
4
5 use Drupal\Core\Form\FormState;
6 use Drupal\Core\Form\FormStateInterface;
7 use Drupal\views\Plugin\Block\ViewsBlock;
8 use Drupal\views\Plugin\views\display\Block as CoreBlock;
9 use Drupal\views\Plugin\views\filter\InOperator;
10
11 /**
12  * Provides a Block display plugin that allows for greater control over Views
13  * block settings.
14  */
15 class Block extends CoreBlock {
16
17   /**
18    * {@inheritdoc}
19    */
20   public function optionsSummary(&$categories, &$options) {
21     parent::optionsSummary($categories, $options);
22     $filtered_allow = array_filter($this->getOption('allow'));
23     $filter_options = [
24       'items_per_page' => $this->t('Items per page'),
25       'offset' => $this->t('Pager offset'),
26       'pager' => $this->t('Pager type'),
27       'hide_fields' => $this->t('Hide fields'),
28       'sort_fields' => $this->t('Reorder fields'),
29       'disable_filters' => $this->t('Disable filters'),
30       'configure_sorts' => $this->t('Configure sorts')
31     ];
32     $filter_intersect = array_intersect_key($filter_options, $filtered_allow);
33
34     $options['allow'] = array(
35       'category' => 'block',
36       'title' => $this->t('Allow settings'),
37       'value' => empty($filtered_allow) ? $this->t('None') : implode(', ', $filter_intersect),
38     );
39   }
40
41   /**
42    * {@inheritdoc}
43    */
44   public function buildOptionsForm(&$form, FormStateInterface $form_state) {
45     parent::buildOptionsForm($form, $form_state);
46     $options = $form['allow']['#options'];
47     $options['offset'] = $this->t('Pager offset');
48     $options['pager'] = $this->t('Pager type');
49     $options['hide_fields'] = $this->t('Hide fields');
50     $options['sort_fields'] = $this->t('Reorder fields');
51     $options['disable_filters'] = $this->t('Disable filters');
52     $options['configure_sorts'] = $this->t('Configure sorts');
53     $form['allow']['#options'] = $options;
54     // Update the items_per_page if set.
55     $defaults = array_filter($form['allow']['#default_value']);
56     if (isset($defaults['items_per_page'])) {
57       $defaults['items_per_page'] = 'items_per_page';
58     }
59     $form['allow']['#default_value'] = $defaults;
60   }
61
62   /**
63    * {@inheritdoc}
64    */
65   public function blockForm(ViewsBlock $block, array &$form, FormStateInterface $form_state) {
66     $form = parent::blockForm($block, $form, $form_state);
67
68     $allow_settings = array_filter($this->getOption('allow'));
69     $block_configuration = $block->getConfiguration();
70
71     // Modify "Items per page" block settings form.
72     if (!empty($allow_settings['items_per_page'])) {
73       // Items per page
74       $form['override']['items_per_page']['#type'] = 'number';
75       unset($form['override']['items_per_page']['#options']);
76     }
77
78     // Provide "Pager offset" block settings form.
79     if (!empty($allow_settings['offset'])) {
80       $form['override']['pager_offset'] = [
81         '#type' => 'number',
82         '#title' => $this->t('Pager offset'),
83         '#default_value' => isset($block_configuration['pager_offset']) ? $block_configuration['pager_offset'] : 0,
84         '#description' => $this->t('For example, set this to 3 and the first 3 items will not be displayed.'),
85       ];
86     }
87
88     // Provide "Pager type" block settings form.
89     if (!empty($allow_settings['pager'])) {
90       $pager_options = [
91         'view' => $this->t('Inherit from view'),
92         'some' => $this->t('Display a specified number of items'),
93         'none' => $this->t('Display all items')
94       ];
95       $form['override']['pager'] = [
96         '#type' => 'radios',
97         '#title' => $this->t('Pager'),
98         '#options' => $pager_options,
99         '#default_value' => isset($block_configuration['pager']) ? $block_configuration['pager'] : 'view'
100       ];
101     }
102
103     // Provide "Hide fields" / "Reorder fields" block settings form.
104     if (!empty($allow_settings['hide_fields']) || !empty($allow_settings['sort_fields'])) {
105       // Set up the configuration table for hiding / sorting fields.
106       $fields = $this->getHandlers('field');
107       $header = [];
108       if (!empty($allow_settings['hide_fields'])) {
109         $header['hide'] = $this->t('Hide');
110       }
111       $header['label'] = $this->t('Label');
112       if (!empty($allow_settings['sort_fields'])) {
113         $header['weight'] = $this->t('Weight');
114       }
115       $form['override']['order_fields'] = [
116         '#type' => 'table',
117         '#header' => $header,
118         '#rows' => array(),
119       ];
120       if (!empty($allow_settings['sort_fields'])) {
121         $form['override']['order_fields']['#tabledrag'] = [
122           [
123             'action' => 'order',
124             'relationship' => 'sibling',
125             'group' => 'field-weight',
126           ]
127         ];
128         $form['override']['order_fields']['#attributes'] = ['id' => 'order-fields'];
129       }
130
131       // Sort available field plugins by their currently configured weight.
132       $sorted_fields = [];
133       if (!empty($allow_settings['sort_fields']) && isset($block_configuration['fields'])) {
134         uasort($block_configuration['fields'], '\Drupal\ctools_views\Plugin\Display\Block::sortFieldsByWeight');
135         foreach (array_keys($block_configuration['fields']) as $field_name) {
136           if (!empty($fields[$field_name])) {
137             $sorted_fields[$field_name] = $fields[$field_name];
138             unset($fields[$field_name]);
139           }
140         }
141         if (!empty($fields)) {
142           foreach ($fields as $field_name => $field_info) {
143             $sorted_fields[$field_name] = $field_info;
144           }
145         }
146       }
147       else {
148         $sorted_fields = $fields;
149       }
150
151       // Add each field to the configuration table.
152       foreach ($sorted_fields as $field_name => $plugin) {
153         $field_label = $plugin->adminLabel();
154         if (!empty($plugin->options['label'])) {
155           $field_label .= ' (' . $plugin->options['label'] . ')';
156         }
157        if (!empty($allow_settings['sort_fields'])) {
158           $form['override']['order_fields'][$field_name]['#attributes']['class'][] = 'draggable';
159         }
160         $form['override']['order_fields'][$field_name]['#weight'] = !empty($block_configuration['fields'][$field_name]['weight']) ? $block_configuration['fields'][$field_name]['weight'] : '';
161         if (!empty($allow_settings['hide_fields'])) {
162           $form['override']['order_fields'][$field_name]['hide'] = [
163             '#type' => 'checkbox',
164             '#default_value' => !empty($block_configuration['fields'][$field_name]['hide']) ? $block_configuration['fields'][$field_name]['hide'] : 0,
165           ];
166         }
167         $form['override']['order_fields'][$field_name]['label'] = [
168           '#markup' => $field_label,
169         ];
170         if (!empty($allow_settings['sort_fields'])) {
171           $form['override']['order_fields'][$field_name]['weight'] = [
172             '#type' => 'weight',
173             '#title' => $this->t('Weight for @title', ['@title' => $field_label]),
174             '#title_display' => 'invisible',
175             '#delta' => 50,
176             '#default_value' => !empty($block_configuration['fields'][$field_name]['weight']) ? $block_configuration['fields'][$field_name]['weight'] : 0,
177             '#attributes' => ['class' => ['field-weight']],
178           ];
179         }
180       }
181     }
182
183     // Provide "Configure filters" / "Disable filters" block settings form.
184     if (!empty($allow_settings['disable_filters'])) {
185       $items = [];
186       foreach ((array) $this->getOption('filters') as $filter_name => $item) {
187         $item['value'] = isset($block_configuration["filter"][$filter_name]['value']) ? $block_configuration["filter"][$filter_name]['value'] : '';
188         $items[$filter_name] = $item;
189       }
190       $this->setOption('filters', $items);
191       $filters = $this->getHandlers('filter');
192
193       // Add a settings form for each exposed filter to configure or hide it.
194       foreach ($filters as $filter_name => $plugin) {
195         if ($plugin->isExposed() && $exposed_info = $plugin->exposedInfo()) {
196           $form['override']['filters'][$filter_name] = [
197             '#type' => 'details',
198             '#title' => $exposed_info['label'],
199           ];
200           $form['override']['filters'][$filter_name]['plugin'] = [
201             '#type' => 'value',
202             '#value' => $plugin,
203           ];
204           // Render "Disable filters" settings form.
205           if (!empty($allow_settings['disable_filters'])) {
206             $form['override']['filters'][$filter_name]['disable'] = [
207               '#type' => 'checkbox',
208               '#title' => $this->t('Disable'),
209               '#default_value' => !empty($block_configuration['filter'][$filter_name]['disable']) ? $block_configuration['filter'][$filter_name]['disable'] : 0,
210             ];
211           }
212         }
213       }
214     }
215
216     // Provide "Configure sorts" block settings form.
217     if (!empty($allow_settings['configure_sorts'])) {
218       $sorts = $this->getHandlers('sort');
219       $options = array(
220         'ASC' => $this->t('Sort ascending'),
221         'DESC' => $this->t('Sort descending'),
222       );
223       foreach ($sorts as $sort_name => $plugin) {
224         $form['override']['sort'][$sort_name] = [
225           '#type' => 'details',
226           '#title' => $plugin->adminLabel(),
227         ];
228         $form['override']['sort'][$sort_name]['plugin'] = [
229           '#type' => 'value',
230           '#value' => $plugin,
231         ];
232         $form['override']['sort'][$sort_name]['order'] = array(
233           '#title' => $this->t('Order'),
234           '#type' => 'radios',
235           '#options' => $options,
236           '#default_value' => $plugin->options['order']
237         );
238
239         // Set default values for sorts for this block.
240         if (!empty($block_configuration["sort"][$sort_name])) {
241           $form['override']['sort'][$sort_name]['order']['#default_value'] = $block_configuration["sort"][$sort_name];
242         }
243       }
244     }
245
246     return $form;
247   }
248
249   /**
250    * {@inheritdoc}
251    */
252   public function blockSubmit(ViewsBlock $block, $form, FormStateInterface $form_state) {
253     // Set default value for items_per_page if left blank.
254     if (empty($form_state->getValue(array('override', 'items_per_page')))) {
255       $form_state->setValue(array('override', 'items_per_page'), "none");
256     }
257
258     parent::blockSubmit($block, $form, $form_state);
259     $configuration = $block->getConfiguration();
260     $allow_settings = array_filter($this->getOption('allow'));
261
262     // Save "Pager type" settings to block configuration.
263     if (!empty($allow_settings['pager'])) {
264       if ($pager = $form_state->getValue(['override', 'pager'])) {
265         $configuration['pager'] = $pager;
266       }
267     }
268
269     // Save "Pager offset" settings to block configuration.
270     if (!empty($allow_settings['offset'])) {
271       $configuration['pager_offset'] = $form_state->getValue(['override', 'pager_offset']);
272     }
273
274     // Save "Hide fields" / "Reorder fields" settings to block configuration.
275     if (!empty($allow_settings['hide_fields']) || !empty($allow_settings['sort_fields'])) {
276       if ($fields = array_filter($form_state->getValue(['override', 'order_fields']))) {
277         uasort($fields, '\Drupal\ctools_views\Plugin\Display\Block::sortFieldsByWeight');
278         $configuration['fields'] = $fields;
279       }
280     }
281
282     // Save "Configure filters" / "Disable filters" settings to block
283     // configuration.
284     unset($configuration['filter']);
285     if (!empty($allow_settings['disable_filters'])) {
286       if ($filters = $form_state->getValue(['override', 'filters'])) {
287         foreach ($filters as $filter_name => $filter) {
288           /** @var \Drupal\views\Plugin\views\filter\FilterPluginBase $plugin */
289           $plugin = $form_state->getValue(['override', 'filters', $filter_name, 'plugin']);
290           $configuration["filter"][$filter_name]['type'] = $plugin->getPluginId();
291
292           // Check if we want to disable this filter.
293           if (!empty($allow_settings['disable_filters'])) {
294             $disable = $form_state->getValue(['override', 'filters', $filter_name, 'disable']);
295             // If marked disabled, we don't really care about other stuff.
296             if ($disable) {
297               $configuration["filter"][$filter_name]['disable'] = $disable;
298               continue;
299             }
300           }
301         }
302       }
303     }
304
305     // Save "Configure sorts" settings to block configuration.
306     if (!empty($allow_settings['configure_sorts'])) {
307       $sorts = $form_state->getValue(['override', 'sort']);
308       foreach ($sorts as $sort_name => $sort) {
309         $plugin = $sort['plugin'];
310         // Check if we want to override the default sort order
311         if ($plugin->options['order'] != $sort['order']) {
312           $configuration['sort'][$sort_name] = $sort['order'];
313         }
314       }
315     }
316
317     $block->setConfiguration($configuration);
318   }
319
320   /**
321    * {@inheritdoc}
322    */
323   public function preBlockBuild(ViewsBlock $block) {
324     parent::preBlockBuild($block);
325
326     $allow_settings = array_filter($this->getOption('allow'));
327     $config = $block->getConfiguration();
328     list(, $display_id) = explode('-', $block->getDerivativeId(), 2);
329
330     // Change pager offset settings based on block configuration.
331     if (!empty($allow_settings['offset'])) {
332       $this->view->setOffset($config['pager_offset']);
333     }
334
335     // Change pager style settings based on block configuration.
336     if (!empty($allow_settings['pager'])) {
337       $pager = $this->view->display_handler->getOption('pager');
338       if (!empty($config['pager']) && $config['pager'] != 'view') {
339         $pager['type'] = $config['pager'];
340       }
341       $this->view->display_handler->setOption('pager', $pager);
342     }
343
344     // Change fields output based on block configuration.
345     if (!empty($allow_settings['hide_fields']) || !empty($allow_settings['sort_fields'])) {
346       if (!empty($config['fields']) && $this->view->getStyle()->usesFields()) {
347         $fields = $this->view->getHandlers('field');
348         uasort($config['fields'], '\Drupal\ctools_views\Plugin\Display\Block::sortFieldsByWeight');
349         $iterate_fields = !empty($allow_settings['sort_fields']) ? $config['fields'] : $fields;
350         foreach (array_keys($iterate_fields) as $field_name) {
351           // Remove each field in sequence and re-add them to sort
352           // appropriately or hide if disabled.
353           $this->view->removeHandler($display_id, 'field', $field_name);
354           if (empty($allow_settings['hide_fields']) || (!empty($allow_settings['hide_fields']) && empty($config['fields'][$field_name]['hide']))) {
355             $this->view->addHandler($display_id, 'field', $fields[$field_name]['table'], $fields[$field_name]['field'], $fields[$field_name], $field_name);
356           }
357         }
358       }
359     }
360
361     // Change filters output based on block configuration.
362     if (!empty($allow_settings['disable_filters'])) {
363       $filters = $this->view->getHandlers('filter', $display_id);
364       foreach ($filters as $filter_name => $filter) {
365         // If we allow disabled filters and this filter is disabled, disable it
366         // and continue.
367         if (!empty($allow_settings['disable_filters']) && !empty($config["filter"][$filter_name]['disable'])) {
368           $this->view->removeHandler($display_id, 'filter', $filter_name);
369           continue;
370         }
371       }
372     }
373
374     // Change sorts based on block configuration.
375     if (!empty($allow_settings['configure_sorts'])) {
376       $sorts = $this->view->getHandlers('sort', $display_id);
377       foreach ($sorts as $sort_name => $sort) {
378         if (!empty($config["sort"][$sort_name])) {
379           $sort['order'] = $config["sort"][$sort_name];
380           $this->view->setHandler($display_id, 'sort', $sort_name, $sort);
381         }
382       }
383     }
384   }
385
386   protected function getFilterOptionsValue(array $filter, array $config) {
387     $plugin_definition = \Drupal::service('plugin.manager.views.filter')->getDefinition($config['type']);
388     if (is_subclass_of($plugin_definition['class'], '\Drupal\views\Plugin\views\filter\InOperator')) {
389       return array_values($config['value']);
390     }
391     return $config['value'][$filter['expose']['identifier']];
392   }
393
394   /**
395    * {@inheritdoc}
396    */
397   public function usesExposed() {
398     $filters = $this->getHandlers('filter');
399     foreach ($filters as $filter_name => $filter) {
400       if ($filter->isExposed() && !empty($filter->exposedInfo())) {
401         return TRUE;
402       }
403     }
404     return FALSE;
405   }
406
407   /**
408    * Exposed widgets typically only work with ajax in Drupal core, however
409    * #2605218 totally breaks the rest of the functionality in this display and
410    * in Core's Block display as well, so we allow non-ajax block views to use
411    * exposed filters and manually set the #action to the current request uri.
412    */
413   public function elementPreRender(array $element) {
414     /** @var \Drupal\views\ViewExecutable $view */
415     $view = $element['#view'];
416     if (!empty($view->exposed_widgets['#action']) && !$view->ajaxEnabled()) {
417       $view->exposed_widgets['#action'] = \Drupal::request()->getRequestUri();
418     }
419     return parent::elementPreRender($element);
420   }
421
422   /**
423    * Sort field config array by weight.
424    *
425    * @param $a
426    * @param $b
427    * @return int
428    */
429   public static function sortFieldsByWeight($a, $b) {
430     $a_weight = isset($a['weight']) ? $a['weight'] : 0;
431     $b_weight = isset($b['weight']) ? $b['weight'] : 0;
432     if ($a_weight == $b_weight) {
433       return 0;
434     }
435     return ($a_weight < $b_weight) ? -1 : 1;
436   }
437
438 }