Updated to Drupal 8.5. Core Media not yet in use.
[yaffs-website] / web / core / modules / views / src / Plugin / views / display / Block.php
1 <?php
2
3 namespace Drupal\views\Plugin\views\display;
4
5 use Drupal\Core\Entity\EntityManagerInterface;
6 use Drupal\Core\Form\FormStateInterface;
7 use Drupal\views\Plugin\Block\ViewsBlock;
8 use Symfony\Component\DependencyInjection\ContainerInterface;
9
10 /**
11  * The plugin that handles a block.
12  *
13  * @ingroup views_display_plugins
14  *
15  * @ViewsDisplay(
16  *   id = "block",
17  *   title = @Translation("Block"),
18  *   help = @Translation("Display the view as a block."),
19  *   theme = "views_view",
20  *   register_theme = FALSE,
21  *   uses_hook_block = TRUE,
22  *   contextual_links_locations = {"block"},
23  *   admin = @Translation("Block")
24  * )
25  *
26  * @see \Drupal\views\Plugin\Block\ViewsBlock
27  * @see \Drupal\views\Plugin\Derivative\ViewsBlock
28  */
29 class Block extends DisplayPluginBase {
30
31   /**
32    * Whether the display allows attachments.
33    *
34    * @var bool
35    */
36   protected $usesAttachments = TRUE;
37
38   /**
39    * The entity manager.
40    *
41    * @var \Drupal\Core\Entity\EntityManagerInterface
42    */
43   protected $entityManager;
44
45   /**
46    * Constructs a new Block instance.
47    *
48    * @param array $configuration
49    *   A configuration array containing information about the plugin instance.
50    * @param string $plugin_id
51    *   The plugin_id for the plugin instance.
52    * @param mixed $plugin_definition
53    *   The plugin implementation definition.
54    * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
55    *   The entity manager.
56    */
57   public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityManagerInterface $entity_manager) {
58     parent::__construct($configuration, $plugin_id, $plugin_definition);
59
60     $this->entityManager = $entity_manager;
61   }
62
63   /**
64    * {@inheritdoc}
65    */
66   public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
67     return new static(
68       $configuration,
69       $plugin_id,
70       $plugin_definition,
71       $container->get('entity.manager')
72     );
73   }
74
75   /**
76    * {@inheritdoc}
77    */
78   protected function defineOptions() {
79     $options = parent::defineOptions();
80
81     $options['block_description'] = ['default' => ''];
82     $options['block_category'] = ['default' => $this->t('Lists (Views)')];
83     $options['block_hide_empty'] = ['default' => FALSE];
84
85     $options['allow'] = [
86       'contains' => [
87         'items_per_page' => ['default' => 'items_per_page'],
88       ],
89     ];
90
91     return $options;
92   }
93
94   /**
95    * Returns plugin-specific settings for the block.
96    *
97    * @param array $settings
98    *   The settings of the block.
99    *
100    * @return array
101    *   An array of block-specific settings to override the defaults provided in
102    *   \Drupal\views\Plugin\Block\ViewsBlock::defaultConfiguration().
103    *
104    * @see \Drupal\views\Plugin\Block\ViewsBlock::defaultConfiguration()
105    */
106   public function blockSettings(array $settings) {
107     $settings['items_per_page'] = 'none';
108     return $settings;
109   }
110
111   /**
112    * The display block handler returns the structure necessary for a block.
113    */
114   public function execute() {
115     // Prior to this being called, the $view should already be set to this
116     // display, and arguments should be set on the view.
117     $element = $this->view->render();
118     if ($this->outputIsEmpty() && $this->getOption('block_hide_empty') && empty($this->view->style_plugin->definition['even empty'])) {
119       return [];
120     }
121     else {
122       return $element;
123     }
124   }
125
126   /**
127    * Provide the summary for page options in the views UI.
128    *
129    * This output is returned as an array.
130    */
131   public function optionsSummary(&$categories, &$options) {
132     parent::optionsSummary($categories, $options);
133
134     $categories['block'] = [
135       'title' => $this->t('Block settings'),
136       'column' => 'second',
137       'build' => [
138         '#weight' => -10,
139       ],
140     ];
141
142     $block_description = strip_tags($this->getOption('block_description'));
143     if (empty($block_description)) {
144       $block_description = $this->t('None');
145     }
146     $block_category = $this->getOption('block_category');
147
148     $options['block_description'] = [
149       'category' => 'block',
150       'title' => $this->t('Block name'),
151       'value' => views_ui_truncate($block_description, 24),
152     ];
153     $options['block_category'] = [
154       'category' => 'block',
155       'title' => $this->t('Block category'),
156       'value' => views_ui_truncate($block_category, 24),
157     ];
158
159     $filtered_allow = array_filter($this->getOption('allow'));
160
161     $options['allow'] = [
162       'category' => 'block',
163       'title' => $this->t('Allow settings'),
164       'value' => empty($filtered_allow) ? $this->t('None') : $this->t('Items per page'),
165     ];
166
167     $options['block_hide_empty'] = [
168       'category' => 'other',
169       'title' => $this->t('Hide block if the view output is empty'),
170       'value' => $this->getOption('block_hide_empty') ? $this->t('Yes') : $this->t('No'),
171     ];
172   }
173
174   /**
175    * Provide the default form for setting options.
176    */
177   public function buildOptionsForm(&$form, FormStateInterface $form_state) {
178     parent::buildOptionsForm($form, $form_state);
179
180     switch ($form_state->get('section')) {
181       case 'block_description':
182         $form['#title'] .= $this->t('Block admin description');
183         $form['block_description'] = [
184           '#type' => 'textfield',
185           '#description' => $this->t('This will appear as the name of this block in administer >> structure >> blocks.'),
186           '#default_value' => $this->getOption('block_description'),
187         ];
188         break;
189       case 'block_category':
190         $form['#title'] .= $this->t('Block category');
191         $form['block_category'] = [
192           '#type' => 'textfield',
193           '#autocomplete_route_name' => 'block.category_autocomplete',
194           '#description' => $this->t('The category this block will appear under on the <a href=":href">blocks placement page</a>.', [':href' => \Drupal::url('block.admin_display')]),
195           '#default_value' => $this->getOption('block_category'),
196         ];
197         break;
198       case 'block_hide_empty':
199         $form['#title'] .= $this->t('Block empty settings');
200
201         $form['block_hide_empty'] = [
202           '#title' => $this->t('Hide block if no result/empty text'),
203           '#type' => 'checkbox',
204           '#description' => $this->t('Hide the block if there is no result and no empty text and no header/footer which is shown on empty result'),
205           '#default_value' => $this->getOption('block_hide_empty'),
206         ];
207         break;
208       case 'exposed_form_options':
209         $this->view->initHandlers();
210         if (!$this->usesExposed() && parent::usesExposed()) {
211           $form['exposed_form_options']['warning'] = [
212             '#weight' => -10,
213             '#markup' => '<div class="messages messages--warning">' . $this->t('Exposed filters in block displays require "Use AJAX" to be set to work correctly.') . '</div>',
214           ];
215         }
216         break;
217       case 'allow':
218         $form['#title'] .= $this->t('Allow settings in the block configuration');
219
220         $options = [
221           'items_per_page' => $this->t('Items per page'),
222         ];
223
224         $allow = array_filter($this->getOption('allow'));
225         $form['allow'] = [
226           '#type' => 'checkboxes',
227           '#default_value' => $allow,
228           '#options' => $options,
229         ];
230         break;
231     }
232   }
233
234   /**
235    * Perform any necessary changes to the form values prior to storage.
236    * There is no need for this function to actually store the data.
237    */
238   public function submitOptionsForm(&$form, FormStateInterface $form_state) {
239     parent::submitOptionsForm($form, $form_state);
240     $section = $form_state->get('section');
241     switch ($section) {
242       case 'block_description':
243       case 'block_category':
244       case 'allow':
245       case 'block_hide_empty':
246         $this->setOption($section, $form_state->getValue($section));
247         break;
248     }
249   }
250
251   /**
252    * Adds the configuration form elements specific to this views block plugin.
253    *
254    * This method allows block instances to override the views items_per_page.
255    *
256    * @param \Drupal\views\Plugin\Block\ViewsBlock $block
257    *   The ViewsBlock plugin.
258    * @param array $form
259    *   The form definition array for the block configuration form.
260    * @param \Drupal\Core\Form\FormStateInterface $form_state
261    *   The current state of the form.
262    *
263    * @return array
264    *   The renderable form array representing the entire configuration form.
265    *
266    * @see \Drupal\views\Plugin\Block\ViewsBlock::blockForm()
267    */
268   public function blockForm(ViewsBlock $block, array &$form, FormStateInterface $form_state) {
269     $allow_settings = array_filter($this->getOption('allow'));
270
271     $block_configuration = $block->getConfiguration();
272
273     foreach ($allow_settings as $type => $enabled) {
274       if (empty($enabled)) {
275         continue;
276       }
277       switch ($type) {
278         case 'items_per_page':
279           $form['override']['items_per_page'] = [
280             '#type' => 'select',
281             '#title' => $this->t('Items per block'),
282             '#options' => [
283               'none' => $this->t('@count (default setting)', ['@count' => $this->getPlugin('pager')->getItemsPerPage()]),
284               5 => 5,
285               10 => 10,
286               20 => 20,
287               40 => 40,
288             ],
289             '#default_value' => $block_configuration['items_per_page'],
290           ];
291           break;
292       }
293     }
294
295     return $form;
296   }
297
298   /**
299    * Handles form validation for the views block configuration form.
300    *
301    * @param \Drupal\views\Plugin\Block\ViewsBlock $block
302    *   The ViewsBlock plugin.
303    * @param array $form
304    *   The form definition array for the block configuration form.
305    * @param \Drupal\Core\Form\FormStateInterface $form_state
306    *   The current state of the form.
307    *
308    * @see \Drupal\views\Plugin\Block\ViewsBlock::blockValidate()
309    */
310   public function blockValidate(ViewsBlock $block, array $form, FormStateInterface $form_state) {
311   }
312
313   /**
314    * Handles form submission for the views block configuration form.
315    *
316    * @param \Drupal\views\Plugin\Block\ViewsBlock $block
317    *   The ViewsBlock plugin.
318    * @param array $form
319    *   The form definition array for the full block configuration form.
320    * @param \Drupal\Core\Form\FormStateInterface $form_state
321    *   The current state of the form.
322    *
323    * @see \Drupal\views\Plugin\Block\ViewsBlock::blockSubmit()
324    */
325   public function blockSubmit(ViewsBlock $block, $form, FormStateInterface $form_state) {
326     if ($items_per_page = $form_state->getValue(['override', 'items_per_page'])) {
327       $block->setConfigurationValue('items_per_page', $items_per_page);
328     }
329     $form_state->unsetValue(['override', 'items_per_page']);
330   }
331
332   /**
333    * Allows to change the display settings right before executing the block.
334    *
335    * @param \Drupal\views\Plugin\Block\ViewsBlock $block
336    *   The block plugin for views displays.
337    */
338   public function preBlockBuild(ViewsBlock $block) {
339     $config = $block->getConfiguration();
340     if ($config['items_per_page'] !== 'none') {
341       $this->view->setItemsPerPage($config['items_per_page']);
342     }
343   }
344
345   /**
346    * Block views use exposed widgets only if AJAX is set.
347    */
348   public function usesExposed() {
349     if ($this->ajaxEnabled()) {
350       return parent::usesExposed();
351     }
352     return FALSE;
353   }
354
355   /**
356    * {@inheritdoc}
357    */
358   public function remove() {
359     parent::remove();
360
361     if ($this->entityManager->hasDefinition('block')) {
362       $plugin_id = 'views_block:' . $this->view->storage->id() . '-' . $this->display['id'];
363       foreach ($this->entityManager->getStorage('block')->loadByProperties(['plugin' => $plugin_id]) as $block) {
364         $block->delete();
365       }
366     }
367   }
368
369 }