You are here

block_style_plugins.module in Block Style Plugins 8.2

Same filename and directory in other branches
  1. 8 block_style_plugins.module

File

block_style_plugins.module
View source
<?php

/**
 * @file
 * Contains block_style_plugins.module.
 */
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\block_style_plugins\BlockFormAlter;
use Drupal\block_style_plugins\SectionFormAlter;

/**
 * Implements hook_help().
 */
function block_style_plugins_help($route_name, RouteMatchInterface $route_match) {
  switch ($route_name) {

    // Main module help for the block_style_plugins module.
    case 'help.page.block_style_plugins':
      $output = '';
      $output .= '<h3>' . t('About') . '</h3>';
      $output .= '<p>' . t('Plugin system for allowing modules or themes to add style configuration to blocks') . '</p>';
      return $output;
    default:
  }
}

/**
 * Implements hook_form_alter().
 */
function block_style_plugins_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  \Drupal::classResolver(BlockFormAlter::class)
    ->layoutBuilderEmbedAlter($form, $form_state, $form_id);
}

/**
 * Implements hook_form_FORM_ID_alter().
 *
 * For the ID form_block.
 */
function block_style_plugins_form_block_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  \Drupal::classResolver(BlockFormAlter::class)
    ->alterForm($form, $form_state);
}

/**
 * Implements hook_preprocess_block().
 */
function block_style_plugins_preprocess_block(&$variables) {

  // Exit if this is a layout builder block since everything is already set.
  if (empty($variables['elements']['#id'])) {
    return $variables;
  }

  // Retrieve a list of style plugin definitions.

  /** @var Drupal\block_style_plugins\Plugin\BlockStyleManager $plugin_manager */
  $plugin_manager = \Drupal::service('plugin.manager.block_style.processor');
  $style_plugins = $plugin_manager
    ->getBlockDefinitions();
  foreach ($style_plugins as $name => $plugin) {
    $variables = $plugin_manager
      ->createInstance($name)
      ->build($variables);
  }
}

/**
 * Implements hook_theme_suggestions_block_alter().
 */
function block_style_plugins_theme_suggestions_block_alter(array &$suggestions, array $variables) {

  // Retrieve a list of style plugin definitions.

  /** @var Drupal\block_style_plugins\Plugin\BlockStyleManager $plugin_manager */
  $plugin_manager = \Drupal::service('plugin.manager.block_style.processor');
  $style_plugins = $plugin_manager
    ->getBlockDefinitions();
  foreach ($style_plugins as $name => $plugin) {
    $suggestions = $plugin_manager
      ->createInstance($name)
      ->themeSuggestion($suggestions, $variables);
  }
}

/**
 * Implements hook_themes_uninstalled().
 */
function block_style_plugins_themes_uninstalled(array $themes) {

  // Clear the Plugins cache when a theme using a plugin is uninstalled.

  /** @var Drupal\block_style_plugins\Plugin\BlockStyleManager $plugin_manager */
  $plugin_manager = \Drupal::service('plugin.manager.block_style.processor');
  $style_plugins = $plugin_manager
    ->getDefinitions();
  $clear_cache = FALSE;
  foreach ($themes as $theme_name) {
    foreach ($style_plugins as $plugin) {
      if ($plugin['provider'] == $theme_name) {
        $clear_cache = TRUE;
        break;
      }
    }
  }

  // Clear all plugin caches.
  if ($clear_cache) {
    \Drupal::service('plugin.cache_clearer')
      ->clearCachedDefinitions();
  }
}

/**
 * Implements hook_form_FORM_ID_alter().
 *
 * For the ID layout_builder_configure_section.
 */
function block_style_plugins_form_layout_builder_configure_section_alter(&$form, FormStateInterface $form_state, $form_id) {
  \Drupal::classResolver(SectionFormAlter::class)
    ->alterForm($form, $form_state);
}

/**
 * Implements hook_preprocess_layout().
 *
 * @todo Replace this with https://www.drupal.org/project/drupal/issues/3062862
 * Until this is done, only Nodes will be supported.
 */
function block_style_plugins_preprocess_layout(&$variables) {
  $block_styles = NULL;

  /** @var \Drupal\layout_builder\SectionStorage\SectionStorageInterface */
  $section_storage = \Drupal::routeMatch()
    ->getParameters()
    ->get('section_storage');

  /** @var \Drupal\node\Entity\Node */
  $node = \Drupal::routeMatch()
    ->getParameters()
    ->get('node');
  if ($section_storage && isset($variables['content']['#attributes']['data-layout-delta'])) {

    // Cast to string since the attribute may be an AttributeValue object and
    // getSection() expects a numeric value.
    $delta = (string) $variables['content']['#attributes']['data-layout-delta'];

    /** @var \Drupal\layout_builder\Section $section */
    $section = $section_storage
      ->getSection($delta);
  }
  elseif ($node) {

    // Remove attributes so we have just the content array.
    $content = array_filter($variables['content'], function ($key) {
      return substr($key, 0, 1) !== '#';
    }, ARRAY_FILTER_USE_KEY);

    // Exit if the current section has no content.
    if (empty($content)) {
      return;
    }

    /** @var \Drupal\layout_builder\Field\LayoutSectionItemList $layout */
    $layout = $node
      ->get('layout_builder__layout');
    $sections = $layout
      ->getSections();

    // Find the current section being processed by comparing its components to
    // the ones in storage.
    foreach ($sections as $possible_section) {
      $component_keys = array_keys($possible_section
        ->getComponents());
      foreach ($content as $content_data) {
        $content_keys = array_filter(array_keys($content_data), function ($id) {

          // Remove attributes.
          return substr($id, 0, 1) !== '#';
        });

        // Check if the current section is the one being preprocessed.
        if ($component_keys == $content_keys) {
          $section = $possible_section;
          break 2;
        }
      }
    }
  }
  if (empty($section)) {
    return;
  }
  $block_styles = $section
    ->getThirdPartySettings('block_style_plugins');
  if ($block_styles) {

    // Retrieve a list of style plugin definitions.

    /** @var Drupal\block_style_plugins\Plugin\BlockStyleManager $plugin_manager */
    $plugin_manager = \Drupal::service('plugin.manager.block_style.processor');
    $available_plugins = $plugin_manager
      ->getSectionDefinitions();
    foreach ($block_styles as $name => $configuration) {

      // Only instantiate plugins that are available.
      if (array_key_exists($name, $available_plugins)) {

        /** @var \Drupal\block_style_plugins\Plugin\BlockStyleInterface $plugin */
        $plugin = $plugin_manager
          ->createInstance($name, $configuration);
        $variables = $plugin
          ->build($variables);
      }
    }
  }
}