diff --git a/core/lib/Drupal/Core/Plugin/DefaultPluginBag.php b/core/lib/Drupal/Core/Plugin/DefaultPluginBag.php index 4ea16b4..9fabf75 100644 --- a/core/lib/Drupal/Core/Plugin/DefaultPluginBag.php +++ b/core/lib/Drupal/Core/Plugin/DefaultPluginBag.php @@ -7,6 +7,7 @@ namespace Drupal\Core\Plugin; +use Drupal\Component\Plugin\Exception\PluginException; use Drupal\Component\Plugin\PluginBag; use Drupal\Component\Plugin\PluginManagerInterface; use Drupal\Component\Utility\MapArray; @@ -67,6 +68,9 @@ public function __construct(PluginManagerInterface $manager, array $configuratio protected function initializePlugin($instance_id) { if (!isset($this->pluginInstances[$instance_id])) { $configuration = $this->configurations[$instance_id]; + if (!isset($configuration[$this->pluginKey])) { + throw new PluginException(format_string("Unknown plugin ID '@instance'.", array('@instance' => $instance_id))); + } $this->pluginInstances[$instance_id] = $this->manager->createInstance($configuration[$this->pluginKey], $configuration); $this->addInstanceID($instance_id); } diff --git a/core/modules/filter/config/filter.format.plain_text.yml b/core/modules/filter/config/filter.format.plain_text.yml index 13217884..ea0a4bd 100644 --- a/core/modules/filter/config/filter.format.plain_text.yml +++ b/core/modules/filter/config/filter.format.plain_text.yml @@ -13,14 +13,14 @@ cache: '1' filters: # Escape all HTML. filter_html_escape: - plugin: filter_html_escape + id: filter_html_escape module: filter status: '1' weight: '-10' settings: { } # Convert URLs into links. filter_url: - plugin: filter_url + id: filter_url module: filter status: '1' weight: '0' @@ -28,7 +28,7 @@ filters: filter_url_length: '72' # Convert linebreaks into paragraphs. filter_autop: - plugin: filter_autop + id: filter_autop module: filter status: '1' weight: '0' diff --git a/core/modules/filter/lib/Drupal/filter/FilterBag.php b/core/modules/filter/lib/Drupal/filter/FilterBag.php index 088c854..fcb8aa9 100644 --- a/core/modules/filter/lib/Drupal/filter/FilterBag.php +++ b/core/modules/filter/lib/Drupal/filter/FilterBag.php @@ -7,7 +7,7 @@ namespace Drupal\filter; -use Drupal\Component\Plugin\PluginManagerInterface; +use Drupal\Component\Plugin\Exception\PluginException; use Drupal\Component\Utility\NestedArray; use Drupal\Core\Plugin\DefaultPluginBag; @@ -26,18 +26,7 @@ class FilterBag extends DefaultPluginBag { /** * {@inheritdoc} */ - public function __construct(PluginManagerInterface $manager, array $configurations = array()) { - parent::__construct($manager, $configurations); - - // Ensure every possible filter has some value in the configuration. - foreach ($this->getDefinitions() as $definition_id => $definition) { - if (!isset($this->configurations[$definition_id])) { - $this->configurations[$definition_id] = $definition; - $this->configurations[$definition_id][$this->pluginKey] = $definition_id; - } - - } - } + protected $pluginKey = 'id'; /** * Retrieves filter definitions and creates an instance for each filter. @@ -45,32 +34,28 @@ public function __construct(PluginManagerInterface $manager, array $configuratio * This is exclusively used for the text format administration page, on which * all available filter plugins are exposed, regardless of whether the current * text format has an active instance. + * + * @todo Refactor text format administration to actually construct/create and + * destruct/remove actual filter plugin instances, using a library approach + * à la blocks. */ public function getAll() { + // Retrieve all available filter plugin definitions. + if (!$this->definitions) { + $this->definitions = $this->manager->getDefinitions(); + } + // Ensure that there is an instance of all available filters. - foreach ($this->getDefinitions() as $plugin_id => $definition) { + // Note that getDefinitions() are keyed by $plugin_id. $instance_id is the + // $plugin_id for filters, since a single filter plugin can only exist once + // in a format. + foreach ($this->definitions as $plugin_id => $definition) { $this->initializePlugin($plugin_id); } return $this->pluginInstances; } /** - * Retrieves definitions from the manager. - * - * Note that getDefinitions() are keyed by $plugin_id. $instance_id is the - * $plugin_id for filters, since a single filter plugin can only exist once - * in a format. - * - * @return array - */ - protected function getDefinitions() { - if (!$this->definitions) { - $this->definitions = $this->manager->getDefinitions(); - } - return $this->definitions; - } - - /** * Updates the configuration for a filter plugin instance. * * If there is no plugin instance yet, a new will be instantiated. Otherwise, @@ -87,6 +72,38 @@ public function setConfig($instance_id, array $configuration) { } /** + * {@inheritdoc} + */ + protected function initializePlugin($instance_id) { + // If the filter was initialized before, just return. + if (isset($this->pluginInstances[$instance_id])) { + return; + } + + // Filters have a 1:1 relationship to text formats and can be added and + // instantiated at any time. + $definition = $this->manager->getDefinition($instance_id); + + if (isset($definition)) { + // $configuration is the whole filter plugin instance configuration, as + // contained in the text format configuration. The default configuration + // is the filter plugin definition. + // @todo Configuration should not be contained in definitions. Move into a + // FilterBase::init() method. + $configuration = $definition; + // Merge the actual configuration into the default configuration. + if (isset($this->configurations[$instance_id])) { + $configuration = NestedArray::mergeDeep($configuration, $this->configurations[$instance_id]); + } + $this->configurations[$instance_id] = $configuration; + parent::initializePlugin($instance_id); + } + else { + throw new PluginException(format_string("Unknown filter plugin ID '@filter'.", array('@filter' => $instance_id))); + } + } + + /** * Sorts all filter plugin instances in this bag. * * @return \Drupal\filter\FilterBag diff --git a/core/modules/filter/lib/Drupal/filter/FilterPluginManager.php b/core/modules/filter/lib/Drupal/filter/FilterPluginManager.php index c04caa8..26b2b2f 100644 --- a/core/modules/filter/lib/Drupal/filter/FilterPluginManager.php +++ b/core/modules/filter/lib/Drupal/filter/FilterPluginManager.php @@ -8,12 +8,12 @@ namespace Drupal\filter; use Drupal\Component\Plugin\PluginManagerBase; -use Drupal\Component\Plugin\Factory\DefaultFactory; use Drupal\Core\Cache\CacheBackendInterface; use Drupal\Core\Language\Language; use Drupal\Core\Plugin\Discovery\AlterDecorator; use Drupal\Core\Plugin\Discovery\AnnotatedClassDiscovery; use Drupal\Core\Plugin\Discovery\CacheDecorator; +use Drupal\Core\Plugin\Factory\ContainerFactory; /** * Manages text processing filters. @@ -36,15 +36,8 @@ public function __construct(\Traversable $namespaces) { $cache_key = 'filter_plugins:' . language(Language::TYPE_INTERFACE)->id; $cache_tags = array('filter_formats' => TRUE); $this->discovery = new CacheDecorator($this->discovery, $cache_key, 'cache', CacheBackendInterface::CACHE_PERMANENT, $cache_tags); - } - /** - * {@inheritdoc} - */ - public function createInstance($plugin_id, array $configuration = array()) { - $plugin_definition = $this->discovery->getDefinition($plugin_id); - $plugin_class = DefaultFactory::getPluginClass($plugin_id, $plugin_definition); - return new $plugin_class($configuration, $plugin_id, $plugin_definition); + $this->factory = new ContainerFactory($this); } } diff --git a/core/modules/filter/lib/Drupal/filter/Plugin/Core/Entity/FilterFormat.php b/core/modules/filter/lib/Drupal/filter/Plugin/Core/Entity/FilterFormat.php index 54d7e24..87d7447 100644 --- a/core/modules/filter/lib/Drupal/filter/Plugin/Core/Entity/FilterFormat.php +++ b/core/modules/filter/lib/Drupal/filter/Plugin/Core/Entity/FilterFormat.php @@ -212,7 +212,7 @@ public function preSave(EntityStorageControllerInterface $storage_controller) { // Determine whether the format can be cached. // @todo This is a derived/computed definition, not configuration. $this->cache = TRUE; - foreach ($this->filters() as $filter) { + foreach ($this->filters()->getAll() as $filter) { if ($filter->status && !$filter->cache) { $this->cache = FALSE; } diff --git a/core/modules/filter/lib/Drupal/filter/Plugin/FilterBase.php b/core/modules/filter/lib/Drupal/filter/Plugin/FilterBase.php index 8b85597..859ff50 100644 --- a/core/modules/filter/lib/Drupal/filter/Plugin/FilterBase.php +++ b/core/modules/filter/lib/Drupal/filter/Plugin/FilterBase.php @@ -100,7 +100,7 @@ public function setConfiguration(array $configuration) { */ public function getConfiguration() { return array( - 'plugin' => $this->getPluginId(), + 'id' => $this->getPluginId(), 'module' => $this->pluginDefinition['module'], 'status' => $this->status, 'weight' => $this->weight, diff --git a/core/modules/filter/lib/Drupal/filter/Plugin/FilterInterface.php b/core/modules/filter/lib/Drupal/filter/Plugin/FilterInterface.php index aeeb4cb..432201c 100644 --- a/core/modules/filter/lib/Drupal/filter/Plugin/FilterInterface.php +++ b/core/modules/filter/lib/Drupal/filter/Plugin/FilterInterface.php @@ -9,7 +9,6 @@ use Drupal\Component\Plugin\PluginInspectionInterface; use Drupal\Core\Plugin\ConfigurablePluginInterface; -use Drupal\Core\Plugin\PluginFormInterface; /** * Defines the interface for text processing filter plugins. diff --git a/core/modules/php/config/filter.format.php_code.yml b/core/modules/php/config/filter.format.php_code.yml index 7aa82d5..289ab21 100644 --- a/core/modules/php/config/filter.format.php_code.yml +++ b/core/modules/php/config/filter.format.php_code.yml @@ -5,7 +5,7 @@ weight: '11' cache: '0' filters: php_code: - plugin: php_code + id: php_code module: php status: '1' weight: '0' diff --git a/core/profiles/standard/config/filter.format.basic_html.yml b/core/profiles/standard/config/filter.format.basic_html.yml index 8369004..3545900 100644 --- a/core/profiles/standard/config/filter.format.basic_html.yml +++ b/core/profiles/standard/config/filter.format.basic_html.yml @@ -7,7 +7,7 @@ roles: cache: '1' filters: filter_html: - plugin: filter_html + id: filter_html module: filter status: '1' weight: '-10' @@ -16,19 +16,19 @@ filters: filter_html_help: '0' filter_html_nofollow: '0' filter_caption: - plugin: filter_caption + id: filter_caption module: filter status: '1' weight: '8' settings: { } filter_html_image_secure: - plugin: filter_html_image_secure + id: filter_html_image_secure module: filter status: '1' weight: '9' settings: { } filter_htmlcorrector: - plugin: filter_htmlcorrector + id: filter_htmlcorrector module: filter status: '1' weight: '10' diff --git a/core/profiles/standard/config/filter.format.full_html.yml b/core/profiles/standard/config/filter.format.full_html.yml index 42a318b..be674aa 100644 --- a/core/profiles/standard/config/filter.format.full_html.yml +++ b/core/profiles/standard/config/filter.format.full_html.yml @@ -7,13 +7,13 @@ roles: cache: '1' filters: filter_caption: - plugin: filter_caption + id: filter_caption module: filter status: '1' weight: '9' settings: { } filter_htmlcorrector: - plugin: filter_htmlcorrector + id: filter_htmlcorrector module: filter status: '1' weight: '10' diff --git a/core/profiles/standard/config/filter.format.restricted_html.yml b/core/profiles/standard/config/filter.format.restricted_html.yml index 3505896..8ed981e 100644 --- a/core/profiles/standard/config/filter.format.restricted_html.yml +++ b/core/profiles/standard/config/filter.format.restricted_html.yml @@ -7,7 +7,7 @@ roles: cache: '1' filters: filter_html: - plugin: filter_html + id: filter_html module: filter status: '1' weight: '-10' @@ -16,20 +16,20 @@ filters: filter_html_help: '1' filter_html_nofollow: '0' filter_autop: - plugin: filter_autop + id: filter_autop module: filter status: '1' weight: '0' settings: { } filter_url: - plugin: filter_url + id: filter_url module: filter status: '1' weight: '0' settings: filter_url_length: '72' filter_htmlcorrector: - plugin: filter_htmlcorrector + id: filter_htmlcorrector module: filter status: '1' weight: '10'