Upgraded drupal core with security updates
[yaffs-website] / web / core / modules / views / src / Plugin / views / sort / SortPluginBase.php
1 <?php
2
3 namespace Drupal\views\Plugin\views\sort;
4
5 use Drupal\Core\Cache\Cache;
6 use Drupal\Core\Cache\CacheableDependencyInterface;
7 use Drupal\Core\Form\FormStateInterface;
8 use Drupal\views\Plugin\views\HandlerBase;
9
10 /**
11  * @defgroup views_sort_handlers Views sort handler plugins
12  * @{
13  * Plugins that handle sorting for Views.
14  *
15  * Sort handlers extend \Drupal\views\Plugin\views\sort:SortPluginBase. They
16  * must be annotated with \Drupal\views\Annotation\ViewsSort annotation, and
17  * they must be in plugin directory Plugin\views\sort.
18  *
19  * @ingroup views_plugins
20  * @see plugin_api
21  */
22
23 /**
24  * Base sort handler that has no options and performs a simple sort.
25  */
26 abstract class SortPluginBase extends HandlerBase implements CacheableDependencyInterface {
27
28   /**
29    * Determine if a sort can be exposed.
30    */
31   public function canExpose() { return TRUE; }
32
33   /**
34    * Called to add the sort to a query.
35    */
36   public function query() {
37     $this->ensureMyTable();
38     // Add the field.
39     $this->query->addOrderBy($this->tableAlias, $this->realField, $this->options['order']);
40   }
41
42   protected function defineOptions() {
43     $options = parent::defineOptions();
44
45     $options['order'] = ['default' => 'ASC'];
46     $options['exposed'] = ['default' => FALSE];
47     $options['expose'] = [
48       'contains' => [
49         'label' => ['default' => ''],
50       ],
51     ];
52     return $options;
53   }
54
55   /**
56    * Display whether or not the sort order is ascending or descending
57    */
58   public function adminSummary() {
59     if (!empty($this->options['exposed'])) {
60       return $this->t('Exposed');
61     }
62     switch ($this->options['order']) {
63       case 'ASC':
64       case 'asc':
65       default:
66         return $this->t('asc');
67
68       case 'DESC';
69       case 'desc';
70         return $this->t('desc');
71     }
72   }
73
74   /**
75    * Basic options for all sort criteria
76    */
77   public function buildOptionsForm(&$form, FormStateInterface $form_state) {
78     parent::buildOptionsForm($form, $form_state);
79     if ($this->canExpose()) {
80       $this->showExposeButton($form, $form_state);
81     }
82     $form['op_val_start'] = ['#value' => '<div class="clearfix">'];
83     $this->showSortForm($form, $form_state);
84     $form['op_val_end'] = ['#value' => '</div>'];
85     if ($this->canExpose()) {
86       $this->showExposeForm($form, $form_state);
87     }
88   }
89
90   /**
91    * Shortcut to display the expose/hide button.
92    */
93   public function showExposeButton(&$form, FormStateInterface $form_state) {
94     $form['expose_button'] = [
95       '#prefix' => '<div class="views-expose clearfix">',
96       '#suffix' => '</div>',
97       // Should always come first
98       '#weight' => -1000,
99     ];
100
101     // Add a checkbox for JS users, which will have behavior attached to it
102     // so it can replace the button.
103     $form['expose_button']['checkbox'] = [
104       '#theme_wrappers' => ['container'],
105       '#attributes' => ['class' => ['js-only']],
106     ];
107     $form['expose_button']['checkbox']['checkbox'] = [
108       '#title' => $this->t('Expose this sort to visitors, to allow them to change it'),
109       '#type' => 'checkbox',
110     ];
111
112     // Then add the button itself.
113     if (empty($this->options['exposed'])) {
114       $form['expose_button']['markup'] = [
115         '#markup' => '<div class="description exposed-description" style="float: left; margin-right:10px">' . $this->t('This sort is not exposed. Expose it to allow the users to change it.') . '</div>',
116       ];
117       $form['expose_button']['button'] = [
118         '#limit_validation_errors' => [],
119         '#type' => 'submit',
120         '#value' => $this->t('Expose sort'),
121         '#submit' => [[$this, 'displayExposedForm']],
122       ];
123       $form['expose_button']['checkbox']['checkbox']['#default_value'] = 0;
124     }
125     else {
126       $form['expose_button']['markup'] = [
127         '#markup' => '<div class="description exposed-description">' . $this->t('This sort is exposed. If you hide it, users will not be able to change it.') . '</div>',
128       ];
129       $form['expose_button']['button'] = [
130         '#limit_validation_errors' => [],
131         '#type' => 'submit',
132         '#value' => $this->t('Hide sort'),
133         '#submit' => [[$this, 'displayExposedForm']],
134       ];
135       $form['expose_button']['checkbox']['checkbox']['#default_value'] = 1;
136     }
137   }
138
139   /**
140    * Simple validate handler
141    */
142   public function validateOptionsForm(&$form, FormStateInterface $form_state) {
143     $this->sortValidate($form, $form_state);
144     if (!empty($this->options['exposed'])) {
145       $this->validateExposeForm($form, $form_state);
146     }
147
148   }
149
150   /**
151    * Simple submit handler
152    */
153   public function submitOptionsForm(&$form, FormStateInterface $form_state) {
154     // Do not store this values.
155     $form_state->unsetValue('expose_button');
156
157     $this->sortSubmit($form, $form_state);
158     if (!empty($this->options['exposed'])) {
159       $this->submitExposeForm($form, $form_state);
160     }
161   }
162
163   /**
164    * Shortcut to display the value form.
165    */
166   protected function showSortForm(&$form, FormStateInterface $form_state) {
167     $options = $this->sortOptions();
168     if (!empty($options)) {
169       $form['order'] = [
170         '#title' => $this->t('Order'),
171         '#type' => 'radios',
172         '#options' => $options,
173         '#default_value' => $this->options['order'],
174       ];
175     }
176   }
177
178   protected function sortValidate(&$form, FormStateInterface $form_state) { }
179
180   public function sortSubmit(&$form, FormStateInterface $form_state) { }
181
182   /**
183    * Provide a list of options for the default sort form.
184    * Should be overridden by classes that don't override sort_form
185    */
186   protected function sortOptions() {
187     return [
188       'ASC' => $this->t('Sort ascending'),
189       'DESC' => $this->t('Sort descending'),
190     ];
191   }
192
193   public function buildExposeForm(&$form, FormStateInterface $form_state) {
194     // #flatten will move everything from $form['expose'][$key] to $form[$key]
195     // prior to rendering. That's why the preRender for it needs to run first,
196     // so that when the next preRender (the one for fieldsets) runs, it gets
197     // the flattened data.
198     array_unshift($form['#pre_render'], [get_class($this), 'preRenderFlattenData']);
199     $form['expose']['#flatten'] = TRUE;
200
201     $form['expose']['label'] = [
202       '#type' => 'textfield',
203       '#default_value' => $this->options['expose']['label'],
204       '#title' => $this->t('Label'),
205       '#required' => TRUE,
206       '#size' => 40,
207       '#weight' => -1,
208    ];
209   }
210
211   /**
212    * Provide default options for exposed sorts.
213    */
214   public function defaultExposeOptions() {
215     $this->options['expose'] = [
216       'label' => $this->definition['title'],
217     ];
218   }
219
220   /**
221    * {@inheritdoc}
222    */
223   public function getCacheMaxAge() {
224     // The result of a sort does not depend on outside information, so by
225     // default it is cacheable.
226     return Cache::PERMANENT;
227   }
228
229   /**
230    * {@inheritdoc}
231    */
232   public function getCacheContexts() {
233     $cache_contexts = [];
234     // Exposed sorts use GET parameters, so it depends on the current URL.
235     if ($this->isExposed()) {
236       $cache_contexts[] = 'url.query_args:sort_by';
237     }
238     return $cache_contexts;
239   }
240
241   /**
242    * {@inheritdoc}
243    */
244   public function getCacheTags() {
245     return [];
246   }
247
248 }
249
250 /**
251  * @}
252  */