3 namespace Drupal\filter;
5 use Drupal\Component\Utility\NestedArray;
6 use Drupal\Core\Plugin\DefaultLazyPluginCollection;
9 * A collection of filters.
11 class FilterPluginCollection extends DefaultLazyPluginCollection {
14 * All possible filter plugin IDs.
18 protected $definitions;
23 * @return \Drupal\filter\Plugin\FilterInterface
25 public function &get($instance_id) {
26 return parent::get($instance_id);
30 * Retrieves filter definitions and creates an instance for each filter.
32 * This is exclusively used for the text format administration page, on which
33 * all available filter plugins are exposed, regardless of whether the current
34 * text format has an active instance.
36 * @todo Refactor text format administration to actually construct/create and
37 * destruct/remove actual filter plugin instances, using a library approach
40 public function getAll() {
41 // Retrieve all available filter plugin definitions.
42 if (!$this->definitions) {
43 $this->definitions = $this->manager->getDefinitions();
44 // Do not allow the null filter to be used directly, only as a fallback.
45 unset($this->definitions['filter_null']);
48 // Ensure that there is an instance of all available filters.
49 // Note that getDefinitions() are keyed by $plugin_id. $instance_id is the
50 // $plugin_id for filters, since a single filter plugin can only exist once
52 foreach ($this->definitions as $plugin_id => $definition) {
53 if (!isset($this->pluginInstances[$plugin_id])) {
54 $this->initializePlugin($plugin_id);
57 return $this->pluginInstances;
63 protected function initializePlugin($instance_id) {
64 // Filters have a 1:1 relationship to text formats and can be added and
65 // instantiated at any time.
66 // @todo $configuration is the whole filter plugin instance configuration,
67 // as contained in the text format configuration. The default
68 // configuration is the filter plugin definition. Configuration should not
69 // be contained in definitions. Move into a FilterBase::init() method.
70 $configuration = $this->manager->getDefinition($instance_id);
71 // Merge the actual configuration into the default configuration.
72 if (isset($this->configurations[$instance_id])) {
73 $configuration = NestedArray::mergeDeep($configuration, $this->configurations[$instance_id]);
75 $this->configurations[$instance_id] = $configuration;
76 parent::initializePlugin($instance_id);
82 public function sort() {
84 return parent::sort();
90 public function sortHelper($aID, $bID) {
91 $a = $this->get($aID);
92 $b = $this->get($bID);
93 if ($a->status != $b->status) {
94 return !empty($a->status) ? -1 : 1;
96 if ($a->weight != $b->weight) {
97 return $a->weight < $b->weight ? -1 : 1;
99 if ($a->provider != $b->provider) {
100 return strnatcasecmp($a->provider, $b->provider);
102 return parent::sortHelper($aID, $bID);
108 public function getConfiguration() {
109 $configuration = parent::getConfiguration();
110 // Remove configuration if it matches the defaults. In self::getAll(), we
111 // load all available filters, in addition to the enabled filters stored in
112 // configuration. In order to prevent those from bleeding through to the
113 // stored configuration, remove all filters that match the default values.
114 // Because filters are disabled by default, this will never remove the
115 // configuration of an enabled filter.
116 foreach ($configuration as $instance_id => $instance_config) {
117 $default_config = [];
118 $default_config['id'] = $instance_id;
119 $default_config += $this->get($instance_id)->defaultConfiguration();
120 if ($default_config === $instance_config) {
121 unset($configuration[$instance_id]);
124 return $configuration;