3 namespace Drupal\views\Plugin\views\display;
5 use Drupal\Component\Plugin\Discovery\CachedDiscoveryInterface;
6 use Drupal\Core\Block\BlockManagerInterface;
7 use Drupal\Core\Entity\EntityManagerInterface;
8 use Drupal\Core\Form\FormStateInterface;
9 use Drupal\views\Plugin\Block\ViewsBlock;
10 use Symfony\Component\DependencyInjection\ContainerInterface;
13 * The plugin that handles a block.
15 * @ingroup views_display_plugins
19 * title = @Translation("Block"),
20 * help = @Translation("Display the view as a block."),
21 * theme = "views_view",
22 * register_theme = FALSE,
23 * uses_hook_block = TRUE,
24 * contextual_links_locations = {"block"},
25 * admin = @Translation("Block")
28 * @see \Drupal\views\Plugin\Block\ViewsBlock
29 * @see \Drupal\views\Plugin\Derivative\ViewsBlock
31 class Block extends DisplayPluginBase {
34 * Whether the display allows attachments.
38 protected $usesAttachments = TRUE;
43 * @var \Drupal\Core\Entity\EntityManagerInterface
45 protected $entityManager;
50 * @var \Drupal\Core\Block\BlockManagerInterface
52 protected $blockManager;
55 * Constructs a new Block instance.
57 * @param array $configuration
58 * A configuration array containing information about the plugin instance.
59 * @param string $plugin_id
60 * The plugin_id for the plugin instance.
61 * @param mixed $plugin_definition
62 * The plugin implementation definition.
63 * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
65 * @param \Drupal\Core\Block\BlockManagerInterface $block_manager
68 public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityManagerInterface $entity_manager, BlockManagerInterface $block_manager) {
69 parent::__construct($configuration, $plugin_id, $plugin_definition);
71 $this->entityManager = $entity_manager;
72 $this->blockManager = $block_manager;
78 public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
83 $container->get('entity.manager'),
84 $container->get('plugin.manager.block')
91 protected function defineOptions() {
92 $options = parent::defineOptions();
94 $options['block_description'] = ['default' => ''];
95 $options['block_category'] = ['default' => $this->t('Lists (Views)')];
96 $options['block_hide_empty'] = ['default' => FALSE];
100 'items_per_page' => ['default' => 'items_per_page'],
108 * Returns plugin-specific settings for the block.
110 * @param array $settings
111 * The settings of the block.
114 * An array of block-specific settings to override the defaults provided in
115 * \Drupal\views\Plugin\Block\ViewsBlock::defaultConfiguration().
117 * @see \Drupal\views\Plugin\Block\ViewsBlock::defaultConfiguration()
119 public function blockSettings(array $settings) {
120 $settings['items_per_page'] = 'none';
125 * The display block handler returns the structure necessary for a block.
127 public function execute() {
128 // Prior to this being called, the $view should already be set to this
129 // display, and arguments should be set on the view.
130 $element = $this->view->render();
131 if ($this->outputIsEmpty() && $this->getOption('block_hide_empty') && empty($this->view->style_plugin->definition['even empty'])) {
140 * Provide the summary for page options in the views UI.
142 * This output is returned as an array.
144 public function optionsSummary(&$categories, &$options) {
145 parent::optionsSummary($categories, $options);
147 $categories['block'] = [
148 'title' => $this->t('Block settings'),
149 'column' => 'second',
155 $block_description = strip_tags($this->getOption('block_description'));
156 if (empty($block_description)) {
157 $block_description = $this->t('None');
159 $block_category = $this->getOption('block_category');
161 $options['block_description'] = [
162 'category' => 'block',
163 'title' => $this->t('Block name'),
164 'value' => views_ui_truncate($block_description, 24),
166 $options['block_category'] = [
167 'category' => 'block',
168 'title' => $this->t('Block category'),
169 'value' => views_ui_truncate($block_category, 24),
172 $filtered_allow = array_filter($this->getOption('allow'));
174 $options['allow'] = [
175 'category' => 'block',
176 'title' => $this->t('Allow settings'),
177 'value' => empty($filtered_allow) ? $this->t('None') : $this->t('Items per page'),
180 $options['block_hide_empty'] = [
181 'category' => 'other',
182 'title' => $this->t('Hide block if the view output is empty'),
183 'value' => $this->getOption('block_hide_empty') ? $this->t('Yes') : $this->t('No'),
188 * Provide the default form for setting options.
190 public function buildOptionsForm(&$form, FormStateInterface $form_state) {
191 parent::buildOptionsForm($form, $form_state);
193 switch ($form_state->get('section')) {
194 case 'block_description':
195 $form['#title'] .= $this->t('Block admin description');
196 $form['block_description'] = [
197 '#type' => 'textfield',
198 '#description' => $this->t('This will appear as the name of this block in administer >> structure >> blocks.'),
199 '#default_value' => $this->getOption('block_description'),
202 case 'block_category':
203 $form['#title'] .= $this->t('Block category');
204 $form['block_category'] = [
205 '#type' => 'textfield',
206 '#autocomplete_route_name' => 'block.category_autocomplete',
207 '#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')]),
208 '#default_value' => $this->getOption('block_category'),
211 case 'block_hide_empty':
212 $form['#title'] .= $this->t('Block empty settings');
214 $form['block_hide_empty'] = [
215 '#title' => $this->t('Hide block if no result/empty text'),
216 '#type' => 'checkbox',
217 '#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'),
218 '#default_value' => $this->getOption('block_hide_empty'),
221 case 'exposed_form_options':
222 $this->view->initHandlers();
223 if (!$this->usesExposed() && parent::usesExposed()) {
224 $form['exposed_form_options']['warning'] = [
226 '#markup' => '<div class="messages messages--warning">' . $this->t('Exposed filters in block displays require "Use AJAX" to be set to work correctly.') . '</div>',
231 $form['#title'] .= $this->t('Allow settings in the block configuration');
234 'items_per_page' => $this->t('Items per page'),
237 $allow = array_filter($this->getOption('allow'));
239 '#type' => 'checkboxes',
240 '#default_value' => $allow,
241 '#options' => $options,
248 * Perform any necessary changes to the form values prior to storage.
249 * There is no need for this function to actually store the data.
251 public function submitOptionsForm(&$form, FormStateInterface $form_state) {
252 parent::submitOptionsForm($form, $form_state);
253 $section = $form_state->get('section');
255 case 'block_description':
256 case 'block_category':
258 case 'block_hide_empty':
259 $this->setOption($section, $form_state->getValue($section));
265 * Adds the configuration form elements specific to this views block plugin.
267 * This method allows block instances to override the views items_per_page.
269 * @param \Drupal\views\Plugin\Block\ViewsBlock $block
270 * The ViewsBlock plugin.
272 * The form definition array for the block configuration form.
273 * @param \Drupal\Core\Form\FormStateInterface $form_state
274 * The current state of the form.
277 * The renderable form array representing the entire configuration form.
279 * @see \Drupal\views\Plugin\Block\ViewsBlock::blockForm()
281 public function blockForm(ViewsBlock $block, array &$form, FormStateInterface $form_state) {
282 $allow_settings = array_filter($this->getOption('allow'));
284 $block_configuration = $block->getConfiguration();
286 foreach ($allow_settings as $type => $enabled) {
287 if (empty($enabled)) {
291 case 'items_per_page':
292 $form['override']['items_per_page'] = [
294 '#title' => $this->t('Items per block'),
296 'none' => $this->t('@count (default setting)', ['@count' => $this->getPlugin('pager')->getItemsPerPage()]),
302 '#default_value' => $block_configuration['items_per_page'],
312 * Handles form validation for the views block configuration form.
314 * @param \Drupal\views\Plugin\Block\ViewsBlock $block
315 * The ViewsBlock plugin.
317 * The form definition array for the block configuration form.
318 * @param \Drupal\Core\Form\FormStateInterface $form_state
319 * The current state of the form.
321 * @see \Drupal\views\Plugin\Block\ViewsBlock::blockValidate()
323 public function blockValidate(ViewsBlock $block, array $form, FormStateInterface $form_state) {
327 * Handles form submission for the views block configuration form.
329 * @param \Drupal\views\Plugin\Block\ViewsBlock $block
330 * The ViewsBlock plugin.
332 * The form definition array for the full block configuration form.
333 * @param \Drupal\Core\Form\FormStateInterface $form_state
334 * The current state of the form.
336 * @see \Drupal\views\Plugin\Block\ViewsBlock::blockSubmit()
338 public function blockSubmit(ViewsBlock $block, $form, FormStateInterface $form_state) {
339 if ($items_per_page = $form_state->getValue(['override', 'items_per_page'])) {
340 $block->setConfigurationValue('items_per_page', $items_per_page);
342 $form_state->unsetValue(['override', 'items_per_page']);
346 * Allows to change the display settings right before executing the block.
348 * @param \Drupal\views\Plugin\Block\ViewsBlock $block
349 * The block plugin for views displays.
351 public function preBlockBuild(ViewsBlock $block) {
352 $config = $block->getConfiguration();
353 if ($config['items_per_page'] !== 'none') {
354 $this->view->setItemsPerPage($config['items_per_page']);
359 * Block views use exposed widgets only if AJAX is set.
361 public function usesExposed() {
362 if ($this->ajaxEnabled()) {
363 return parent::usesExposed();
371 public function remove() {
374 if ($this->entityManager->hasDefinition('block')) {
375 $plugin_id = 'views_block:' . $this->view->storage->id() . '-' . $this->display['id'];
376 foreach ($this->entityManager->getStorage('block')->loadByProperties(['plugin' => $plugin_id]) as $block) {
380 if ($this->blockManager instanceof CachedDiscoveryInterface) {
381 $this->blockManager->clearCachedDefinitions();