"Fossies" - the Fresh Open Source Software Archive

Member "drupal-8.9.10/core/modules/breakpoint/src/BreakpointManager.php" (26 Nov 2020, 7987 Bytes) of package /linux/www/drupal-8.9.10.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) PHP source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "BreakpointManager.php" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 9.0.8_vs_9.1.0-rc1.

    1 <?php
    2 
    3 namespace Drupal\breakpoint;
    4 
    5 use Drupal\Core\Cache\Cache;
    6 use Drupal\Core\Cache\CacheBackendInterface;
    7 use Drupal\Core\Extension\ModuleHandlerInterface;
    8 use Drupal\Core\Extension\ThemeHandlerInterface;
    9 use Drupal\Core\Plugin\DefaultPluginManager;
   10 use Drupal\Core\Plugin\Discovery\ContainerDerivativeDiscoveryDecorator;
   11 use Drupal\Core\Plugin\Discovery\YamlDiscovery;
   12 use Drupal\Core\Plugin\Factory\ContainerFactory;
   13 use Drupal\Core\StringTranslation\StringTranslationTrait;
   14 use Drupal\Core\StringTranslation\TranslationInterface;
   15 
   16 /**
   17  * Defines a breakpoint plugin manager to deal with breakpoints.
   18  *
   19  * Extension can define breakpoints in a EXTENSION_NAME.breakpoints.yml file
   20  * contained in the extension's base directory. Each breakpoint has the
   21  * following structure:
   22  * @code
   23  *   MACHINE_NAME:
   24  *     label: STRING
   25  *     mediaQuery: STRING
   26  *     weight: INTEGER
   27  *     multipliers:
   28  *       - STRING
   29  * @endcode
   30  * For example:
   31  * @code
   32  * bartik.mobile:
   33  *   label: mobile
   34  *   mediaQuery: '(min-width: 0px)'
   35  *   weight: 0
   36  *   multipliers:
   37  *     - 1x
   38  *     - 2x
   39  * @endcode
   40  * Optionally a breakpoint can provide a group key. By default an extensions
   41  * breakpoints will be placed in a group labelled with the extension name.
   42  *
   43  * @see \Drupal\breakpoint\Breakpoint
   44  * @see \Drupal\breakpoint\BreakpointInterface
   45  * @see plugin_api
   46  */
   47 class BreakpointManager extends DefaultPluginManager implements BreakpointManagerInterface {
   48   use StringTranslationTrait;
   49 
   50   /**
   51    * {@inheritdoc}
   52    */
   53   protected $defaults = [
   54     // Human readable label for breakpoint.
   55     'label' => '',
   56     // The media query for the breakpoint.
   57     'mediaQuery' => '',
   58     // Weight used for ordering breakpoints.
   59     'weight' => 0,
   60     // Breakpoint multipliers.
   61     'multipliers' => [],
   62     // The breakpoint group.
   63     'group' => '',
   64     // Default class for breakpoint implementations.
   65     'class' => 'Drupal\breakpoint\Breakpoint',
   66     // The plugin id. Set by the plugin system based on the top-level YAML key.
   67     'id' => '',
   68   ];
   69 
   70   /**
   71    * The theme handler.
   72    *
   73    * @var \Drupal\Core\Extension\ThemeHandlerInterface
   74    */
   75   protected $themeHandler;
   76 
   77   /**
   78    * Static cache of breakpoints keyed by group.
   79    *
   80    * @var array
   81    */
   82   protected $breakpointsByGroup;
   83 
   84   /**
   85    * The plugin instances.
   86    *
   87    * @var array
   88    */
   89   protected $instances = [];
   90 
   91   /**
   92    * Constructs a new BreakpointManager instance.
   93    *
   94    * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
   95    *   The module handler.
   96    * @param \Drupal\Core\Extension\ThemeHandlerInterface $theme_handler
   97    *   The theme handler.
   98    * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
   99    *   The cache backend.
  100    * @param \Drupal\Core\StringTranslation\TranslationInterface $string_translation
  101    *   The string translation service.
  102    */
  103   public function __construct(ModuleHandlerInterface $module_handler, ThemeHandlerInterface $theme_handler, CacheBackendInterface $cache_backend, TranslationInterface $string_translation) {
  104     $this->factory = new ContainerFactory($this);
  105     $this->moduleHandler = $module_handler;
  106     $this->themeHandler = $theme_handler;
  107     $this->setStringTranslation($string_translation);
  108     $this->alterInfo('breakpoints');
  109     $this->setCacheBackend($cache_backend, 'breakpoints', ['breakpoints']);
  110   }
  111 
  112   /**
  113    * {@inheritdoc}
  114    */
  115   protected function getDiscovery() {
  116     if (!isset($this->discovery)) {
  117       $this->discovery = new YamlDiscovery('breakpoints', $this->moduleHandler->getModuleDirectories() + $this->themeHandler->getThemeDirectories());
  118       $this->discovery = new ContainerDerivativeDiscoveryDecorator($this->discovery);
  119     }
  120     return $this->discovery;
  121   }
  122 
  123   /**
  124    * {@inheritdoc}
  125    */
  126   public function processDefinition(&$definition, $plugin_id) {
  127     parent::processDefinition($definition, $plugin_id);
  128     // Allow custom groups and therefore more than one group per extension.
  129     if (empty($definition['group'])) {
  130       $definition['group'] = $definition['provider'];
  131     }
  132     // Ensure a 1x multiplier exists.
  133     if (!in_array('1x', $definition['multipliers'])) {
  134       $definition['multipliers'][] = '1x';
  135     }
  136     // Ensure that multipliers are sorted correctly.
  137     sort($definition['multipliers']);
  138   }
  139 
  140   /**
  141    * {@inheritdoc}
  142    */
  143   protected function providerExists($provider) {
  144     return $this->moduleHandler->moduleExists($provider) || $this->themeHandler->themeExists($provider);
  145   }
  146 
  147   /**
  148    * {@inheritdoc}
  149    */
  150   public function getBreakpointsByGroup($group) {
  151     if (!isset($this->breakpointsByGroup[$group])) {
  152       if ($cache = $this->cacheBackend->get($this->cacheKey . ':' . $group)) {
  153         $this->breakpointsByGroup[$group] = $cache->data;
  154       }
  155       else {
  156         $breakpoints = [];
  157         foreach ($this->getDefinitions() as $plugin_id => $plugin_definition) {
  158           if ($plugin_definition['group'] == $group) {
  159             $breakpoints[$plugin_id] = $plugin_definition;
  160           }
  161         }
  162         uasort($breakpoints, ['Drupal\Component\Utility\SortArray', 'sortByWeightElement']);
  163         $this->cacheBackend->set($this->cacheKey . ':' . $group, $breakpoints, Cache::PERMANENT, ['breakpoints']);
  164         $this->breakpointsByGroup[$group] = $breakpoints;
  165       }
  166     }
  167 
  168     $instances = [];
  169     foreach ($this->breakpointsByGroup[$group] as $plugin_id => $definition) {
  170       if (!isset($this->instances[$plugin_id])) {
  171         $this->instances[$plugin_id] = $this->createInstance($plugin_id);
  172       }
  173       $instances[$plugin_id] = $this->instances[$plugin_id];
  174     }
  175     return $instances;
  176   }
  177 
  178   /**
  179    * {@inheritdoc}
  180    */
  181   public function getGroups() {
  182     // Use a double colon so as to not clash with the cache for each group.
  183     if ($cache = $this->cacheBackend->get($this->cacheKey . '::groups')) {
  184       $groups = $cache->data;
  185     }
  186     else {
  187       $groups = [];
  188       foreach ($this->getDefinitions() as $plugin_definition) {
  189         if (!isset($groups[$plugin_definition['group']])) {
  190           $groups[$plugin_definition['group']] = $plugin_definition['group'];
  191         }
  192       }
  193       $this->cacheBackend->set($this->cacheKey . '::groups', $groups, Cache::PERMANENT, ['breakpoints']);
  194     }
  195     // Get the labels. This is not cacheable due to translation.
  196     $group_labels = [];
  197     foreach ($groups as $group) {
  198       $group_labels[$group] = $this->getGroupLabel($group);
  199     }
  200     asort($group_labels);
  201     return $group_labels;
  202   }
  203 
  204   /**
  205    * {@inheritdoc}
  206    */
  207   public function getGroupProviders($group) {
  208     $providers = [];
  209     $breakpoints = $this->getBreakpointsByGroup($group);
  210     foreach ($breakpoints as $breakpoint) {
  211       $provider = $breakpoint->getProvider();
  212       $extension = FALSE;
  213       if ($this->moduleHandler->moduleExists($provider)) {
  214         $extension = $this->moduleHandler->getModule($provider);
  215       }
  216       elseif ($this->themeHandler->themeExists($provider)) {
  217         $extension = $this->themeHandler->getTheme($provider);
  218       }
  219       if ($extension) {
  220         $providers[$extension->getName()] = $extension->getType();
  221       }
  222     }
  223     return $providers;
  224   }
  225 
  226   /**
  227    * {@inheritdoc}
  228    */
  229   public function clearCachedDefinitions() {
  230     parent::clearCachedDefinitions();
  231     $this->breakpointsByGroup = NULL;
  232     $this->instances = [];
  233   }
  234 
  235   /**
  236    * Gets the label for a breakpoint group.
  237    *
  238    * @param string $group
  239    *   The breakpoint group.
  240    *
  241    * @return string
  242    *   The label.
  243    */
  244   protected function getGroupLabel($group) {
  245     // Extension names are not translatable.
  246     if ($this->moduleHandler->moduleExists($group)) {
  247       $label = $this->moduleHandler->getName($group);
  248     }
  249     elseif ($this->themeHandler->themeExists($group)) {
  250       $label = $this->themeHandler->getName($group);
  251     }
  252     else {
  253       // Custom group label that should be translatable.
  254       $label = $this->t($group, [], ['context' => 'breakpoint']);
  255     }
  256     return $label;
  257   }
  258 
  259 }