commerce-8.x-2.8/modules/log/src/LogTemplateManager.php
modules/log/src/LogTemplateManager.php
<?php namespace Drupal\commerce_log; use Drupal\commerce_log\Plugin\LogTemplate\LogTemplate; use Drupal\Component\Plugin\Exception\PluginException; use Drupal\Component\Utility\Html; use Drupal\Component\Utility\Xss; use Drupal\Core\Cache\CacheBackendInterface; use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Plugin\DefaultPluginManager; use Drupal\Core\Plugin\Discovery\ContainerDerivativeDiscoveryDecorator; use Drupal\Core\Plugin\Discovery\YamlDiscovery; /** * Manages discovery and instantiation of commerce_log_template plugins. * * @see plugin_api */ class LogTemplateManager extends DefaultPluginManager implements LogTemplateManagerInterface { /** * The log category manager. * * @var \Drupal\commerce_log\LogCategoryManagerInterface */ protected $categoryManager; /** * Default values for each commerce_log_template plugin. * * @var array */ protected $defaults = [ 'id' => '', 'label' => '', 'template' => '', 'category' => '', 'class' => LogTemplate::class, ]; /** * Constructs a new LogTemplateManager object. * * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler * The module handler. * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend * The cache backend. * @param \Drupal\commerce_log\LogCategoryManagerInterface $category_manager * The log category manager. */ public function __construct(ModuleHandlerInterface $module_handler, CacheBackendInterface $cache_backend, LogCategoryManagerInterface $category_manager) { $this->moduleHandler = $module_handler; $this->setCacheBackend($cache_backend, 'commerce_log_template', ['commerce_log_template']); $this->categoryManager = $category_manager; } /** * {@inheritdoc} */ protected function getDiscovery() { if (!isset($this->discovery)) { $this->discovery = new YamlDiscovery('commerce_log_templates', $this->moduleHandler->getModuleDirectories()); $this->discovery->addTranslatableProperty('label', 'label_context'); $this->discovery = new ContainerDerivativeDiscoveryDecorator($this->discovery); } return $this->discovery; } /** * {@inheritdoc} */ public function processDefinition(&$definition, $plugin_id) { parent::processDefinition($definition, $plugin_id); $definition['id'] = $plugin_id; foreach (['label', 'category', 'template'] as $required_property) { if (empty($definition[$required_property])) { throw new PluginException(sprintf('The commerce_log_template %s must define the %s property.', $plugin_id, $required_property)); } } if (!$this->isStringSafe($definition['template'])) { throw new PluginException(sprintf('The commerce_log_template %s does not have a valid template string.', $plugin_id)); } } /** * {@inheritdoc} */ public function getLabelsByCategory($entity_type_id = NULL) { $definitions = $this->getSortedDefinitions(); $category_labels = $this->getCategoryLabels($entity_type_id); $grouped_definitions = []; foreach ($definitions as $id => $definition) { $category_id = $definition['category']; if (!isset($category_labels[$category_id])) { // Don't return log templates for categories ignored due to their entity type. continue; } $category_label = $category_labels[$category_id]; $grouped_definitions[$category_label][$id] = $definition['label']; } return $grouped_definitions; } /** * Gets the sorted commerce_log_template plugin definitions. * * @return array * The commerce_log_template plugin definitions, sorted by category and label. */ protected function getSortedDefinitions() { // Sort the plugins first by category, then by label. $definitions = $this->getDefinitions(); uasort($definitions, function ($a, $b) { if ($a['category'] != $b['category']) { return strnatcasecmp($a['category'], $b['category']); } return strnatcasecmp($a['label'], $b['label']); }); return $definitions; } /** * Gets a list of category labels for the given entity type ID. * * @param string $entity_type_id * The entity type ID. * * @return array * A list of categories labels keyed by ID. */ protected function getCategoryLabels($entity_type_id = NULL) { $category_definitions = $this->categoryManager->getDefinitionsByEntityType($entity_type_id); $category_labels = array_map(function ($category_definition) { return (string) $category_definition['label']; }, $category_definitions); natcasesort($category_labels); return $category_labels; } /** * Checks whether a string is safe for translation. * * A copy of locale_string_is_safe, made to avoid a dependency on Locale. * * @param string $string * The string. * * @return bool * TRUE if the string is safe, FALSE otherwise. * * @see locale_string_is_safe() */ protected function isStringSafe($string) { $string = preg_replace('/\[[a-z0-9_-]+(:[a-z0-9_-]+)+\]/i', '', $string); return Html::decodeEntities($string) == Html::decodeEntities(Xss::filter($string, ['a', 'abbr', 'acronym', 'address', 'b', 'bdo', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'col', 'colcategory', 'dd', 'del', 'dfn', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'ins', 'kbd', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'sub', 'sup', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'])); } }