BlockManager.php 3.32 KB
Newer Older
1 2 3
<?php

/**
4
 * @file
5
 * Contains \Drupal\Core\Block\BlockManager.
6 7
 */

8
namespace Drupal\Core\Block;
9

10
use Drupal\Core\Cache\CacheBackendInterface;
11
use Drupal\Core\Extension\ModuleHandlerInterface;
12
use Drupal\Core\Plugin\Context\ContextAwarePluginManagerTrait;
13
use Drupal\Core\Plugin\DefaultPluginManager;
14
use Drupal\Core\StringTranslation\StringTranslationTrait;
15

16 17 18 19 20
/**
 * Manages discovery and instantiation of block plugins.
 *
 * @todo Add documentation to this class.
 *
21
 * @see \Drupal\Core\Block\BlockPluginInterface
22
 */
23 24
class BlockManager extends DefaultPluginManager implements BlockManagerInterface {

25
  use StringTranslationTrait;
26
  use ContextAwarePluginManagerTrait;
27

28 29 30 31 32 33 34
  /**
   * An array of all available modules and their data.
   *
   * @var array
   */
  protected $moduleData;

35
  /**
36
   * Constructs a new \Drupal\Core\Block\BlockManager object.
37
   *
38 39
   * @param \Traversable $namespaces
   *   An object that implements \Traversable which contains the root paths
40 41 42 43 44
   *   keyed by the corresponding namespace to look for plugin implementations.
   * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
   *   Cache backend instance to use.
   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
   *   The module handler to invoke the alter hook with.
45
   */
46
  public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) {
47
    parent::__construct('Plugin/Block', $namespaces, $module_handler, 'Drupal\Core\Block\BlockPluginInterface', 'Drupal\Core\Block\Annotation\Block');
48

49
    $this->alterInfo('block');
50
    $this->setCacheBackend($cache_backend, 'block_plugins');
51
  }
52 53 54 55 56 57 58 59

  /**
   * {@inheritdoc}
   */
  public function processDefinition(&$definition, $plugin_id) {
    parent::processDefinition($definition, $plugin_id);

    // Ensure that every block has a category.
60
    if (empty($definition['category'])) {
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
      $definition['category'] = $this->getModuleName($definition['provider']);
    }
  }

  /**
   * Gets the name of the module.
   *
   * @param string $module
   *   The machine name of a module.
   *
   * @return string
   *   The human-readable module name if it exists, otherwise the
   *   machine-readable module name.
   */
  protected function getModuleName($module) {
    // Gather module data.
    if (!isset($this->moduleData)) {
      $this->moduleData = system_get_info('module');
    }
    // If the module exists, return its human-readable name.
    if (isset($this->moduleData[$module])) {
      return $this->t($this->moduleData[$module]['name']);
    }
    // Otherwise, return the machine name.
    return $module;
  }

88
  /**
89
   * {@inheritdoc}
90 91 92 93 94 95 96 97 98
   */
  public function getCategories() {
    $categories = array_unique(array_values(array_map(function ($definition) {
      return $definition['category'];
    }, $this->getDefinitions())));
    natcasesort($categories);
    return $categories;
  }

99 100 101 102 103
  /**
   * {@inheritdoc}
   */
  public function getSortedDefinitions() {
    // Sort the plugins first by category, then by label.
104
    $definitions = $this->getDefinitionsForContexts();
105 106 107 108 109 110 111 112 113
    uasort($definitions, function ($a, $b) {
      if ($a['category'] != $b['category']) {
        return strnatcasecmp($a['category'], $b['category']);
      }
      return strnatcasecmp($a['admin_label'], $b['admin_label']);
    });
    return $definitions;
  }

114
}