Mercurial > hg > cmmr2012-drupal-site
comparison core/modules/ckeditor/src/CKEditorPluginManager.php @ 0:c75dbcec494b
Initial commit from drush-created site
author | Chris Cannam |
---|---|
date | Thu, 05 Jul 2018 14:24:15 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:c75dbcec494b |
---|---|
1 <?php | |
2 | |
3 namespace Drupal\ckeditor; | |
4 | |
5 use Drupal\Component\Utility\NestedArray; | |
6 use Drupal\Core\Form\FormStateInterface; | |
7 use Drupal\Core\Plugin\DefaultPluginManager; | |
8 use Drupal\Core\Cache\CacheBackendInterface; | |
9 use Drupal\Core\Extension\ModuleHandlerInterface; | |
10 use Drupal\editor\Entity\Editor; | |
11 | |
12 /** | |
13 * Provides a CKEditor Plugin plugin manager. | |
14 * | |
15 * @see \Drupal\ckeditor\CKEditorPluginInterface | |
16 * @see \Drupal\ckeditor\CKEditorPluginButtonsInterface | |
17 * @see \Drupal\ckeditor\CKEditorPluginContextualInterface | |
18 * @see \Drupal\ckeditor\CKEditorPluginConfigurableInterface | |
19 * @see \Drupal\ckeditor\CKEditorPluginCssInterface | |
20 * @see \Drupal\ckeditor\CKEditorPluginBase | |
21 * @see \Drupal\ckeditor\Annotation\CKEditorPlugin | |
22 * @see plugin_api | |
23 */ | |
24 class CKEditorPluginManager extends DefaultPluginManager { | |
25 | |
26 /** | |
27 * Constructs a CKEditorPluginManager object. | |
28 * | |
29 * @param \Traversable $namespaces | |
30 * An object that implements \Traversable which contains the root paths | |
31 * keyed by the corresponding namespace to look for plugin implementations. | |
32 * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend | |
33 * Cache backend instance to use. | |
34 * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler | |
35 * The module handler to invoke the alter hook with. | |
36 */ | |
37 public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) { | |
38 parent::__construct('Plugin/CKEditorPlugin', $namespaces, $module_handler, 'Drupal\ckeditor\CKEditorPluginInterface', 'Drupal\ckeditor\Annotation\CKEditorPlugin'); | |
39 $this->alterInfo('ckeditor_plugin_info'); | |
40 $this->setCacheBackend($cache_backend, 'ckeditor_plugins'); | |
41 } | |
42 | |
43 /** | |
44 * Retrieves enabled plugins' files, keyed by plugin ID. | |
45 * | |
46 * For CKEditor plugins that implement: | |
47 * - CKEditorPluginButtonsInterface, not CKEditorPluginContextualInterface, | |
48 * a plugin is enabled if at least one of its buttons is in the toolbar; | |
49 * - CKEditorPluginContextualInterface, not CKEditorPluginButtonsInterface, | |
50 * a plugin is enabled if its isEnabled() method returns TRUE | |
51 * - both of these interfaces, a plugin is enabled if either is the case. | |
52 * | |
53 * Internal plugins (those that are part of the bundled build of CKEditor) are | |
54 * excluded by default, since they are loaded implicitly. If you need to know | |
55 * even implicitly loaded (i.e. internal) plugins, then set the optional | |
56 * second parameter. | |
57 * | |
58 * @param \Drupal\editor\Entity\Editor $editor | |
59 * A configured text editor object. | |
60 * @param bool $include_internal_plugins | |
61 * Defaults to FALSE. When set to TRUE, plugins whose isInternal() method | |
62 * returns TRUE will also be included. | |
63 * @return array | |
64 * A list of the enabled CKEditor plugins, with the plugin IDs as keys and | |
65 * the Drupal root-relative plugin files as values. | |
66 * For internal plugins, the value is NULL. | |
67 */ | |
68 public function getEnabledPluginFiles(Editor $editor, $include_internal_plugins = FALSE) { | |
69 $plugins = array_keys($this->getDefinitions()); | |
70 $toolbar_buttons = $this->getEnabledButtons($editor); | |
71 $enabled_plugins = []; | |
72 $additional_plugins = []; | |
73 | |
74 foreach ($plugins as $plugin_id) { | |
75 $plugin = $this->createInstance($plugin_id); | |
76 | |
77 if (!$include_internal_plugins && $plugin->isInternal()) { | |
78 continue; | |
79 } | |
80 | |
81 $enabled = FALSE; | |
82 // Enable this plugin if it provides a button that has been enabled. | |
83 if ($plugin instanceof CKEditorPluginButtonsInterface) { | |
84 $plugin_buttons = array_keys($plugin->getButtons()); | |
85 $enabled = (count(array_intersect($toolbar_buttons, $plugin_buttons)) > 0); | |
86 } | |
87 // Otherwise enable this plugin if it declares itself as enabled. | |
88 if (!$enabled && $plugin instanceof CKEditorPluginContextualInterface) { | |
89 $enabled = $plugin->isEnabled($editor); | |
90 } | |
91 | |
92 if ($enabled) { | |
93 $enabled_plugins[$plugin_id] = ($plugin->isInternal()) ? NULL : $plugin->getFile(); | |
94 // Check if this plugin has dependencies that also need to be enabled. | |
95 $additional_plugins = array_merge($additional_plugins, array_diff($plugin->getDependencies($editor), $additional_plugins)); | |
96 } | |
97 } | |
98 | |
99 // Add the list of dependent plugins. | |
100 foreach ($additional_plugins as $plugin_id) { | |
101 $plugin = $this->createInstance($plugin_id); | |
102 $enabled_plugins[$plugin_id] = ($plugin->isInternal()) ? NULL : $plugin->getFile(); | |
103 } | |
104 | |
105 // Always return plugins in the same order. | |
106 asort($enabled_plugins); | |
107 | |
108 return $enabled_plugins; | |
109 } | |
110 | |
111 /** | |
112 * Gets the enabled toolbar buttons in the given text editor instance. | |
113 * | |
114 * @param \Drupal\editor\Entity\Editor $editor | |
115 * A configured text editor object. | |
116 * | |
117 * @return string[] | |
118 * A list of the toolbar buttons enabled in the given text editor instance. | |
119 */ | |
120 public static function getEnabledButtons(Editor $editor) { | |
121 $toolbar_rows = []; | |
122 $settings = $editor->getSettings(); | |
123 foreach ($settings['toolbar']['rows'] as $row_number => $row) { | |
124 $toolbar_rows[] = array_reduce($settings['toolbar']['rows'][$row_number], function (&$result, $button_group) { | |
125 return array_merge($result, $button_group['items']); | |
126 }, []); | |
127 } | |
128 return array_unique(NestedArray::mergeDeepArray($toolbar_rows)); | |
129 } | |
130 | |
131 /** | |
132 * Retrieves all available CKEditor buttons, keyed by plugin ID. | |
133 * | |
134 * @return array | |
135 * All available CKEditor buttons, with plugin IDs as keys and button | |
136 * metadata (as implemented by getButtons()) as values. | |
137 * | |
138 * @see \Drupal\ckeditor\CKEditorPluginButtonsInterface::getButtons() | |
139 */ | |
140 public function getButtons() { | |
141 $plugins = array_keys($this->getDefinitions()); | |
142 $buttons_plugins = []; | |
143 | |
144 foreach ($plugins as $plugin_id) { | |
145 $plugin = $this->createInstance($plugin_id); | |
146 if ($plugin instanceof CKEditorPluginButtonsInterface) { | |
147 $buttons_plugins[$plugin_id] = $plugin->getButtons(); | |
148 } | |
149 } | |
150 | |
151 return $buttons_plugins; | |
152 } | |
153 | |
154 /** | |
155 * Injects the CKEditor plugins settings forms as a vertical tabs subform. | |
156 * | |
157 * @param array &$form | |
158 * A reference to an associative array containing the structure of the form. | |
159 * @param \Drupal\Core\Form\FormStateInterface $form_state | |
160 * The current state of the form. | |
161 * @param \Drupal\editor\Entity\Editor $editor | |
162 * A configured text editor object. | |
163 */ | |
164 public function injectPluginSettingsForm(array &$form, FormStateInterface $form_state, Editor $editor) { | |
165 $definitions = $this->getDefinitions(); | |
166 | |
167 foreach (array_keys($definitions) as $plugin_id) { | |
168 $plugin = $this->createInstance($plugin_id); | |
169 if ($plugin instanceof CKEditorPluginConfigurableInterface) { | |
170 $plugin_settings_form = []; | |
171 $form['plugins'][$plugin_id] = [ | |
172 '#type' => 'details', | |
173 '#title' => $definitions[$plugin_id]['label'], | |
174 '#open' => TRUE, | |
175 '#group' => 'editor][settings][plugin_settings', | |
176 '#attributes' => [ | |
177 'data-ckeditor-plugin-id' => $plugin_id, | |
178 ], | |
179 ]; | |
180 // Provide enough metadata for the drupal.ckeditor.admin library to | |
181 // allow it to automatically show/hide the vertical tab containing the | |
182 // settings for this plugin. Only do this if it's a CKEditor plugin that | |
183 // just provides buttons, don't do this if it's a contextually enabled | |
184 // CKEditor plugin. After all, in the latter case, we can't know when | |
185 // its settings should be shown! | |
186 if ($plugin instanceof CKEditorPluginButtonsInterface && !$plugin instanceof CKEditorPluginContextualInterface) { | |
187 $form['plugins'][$plugin_id]['#attributes']['data-ckeditor-buttons'] = implode(' ', array_keys($plugin->getButtons())); | |
188 } | |
189 $form['plugins'][$plugin_id] += $plugin->settingsForm($plugin_settings_form, $form_state, $editor); | |
190 } | |
191 } | |
192 } | |
193 | |
194 /** | |
195 * Retrieves enabled plugins' iframe instance CSS files, keyed by plugin ID. | |
196 * | |
197 * @param \Drupal\editor\Entity\Editor $editor | |
198 * A configured text editor object. | |
199 * | |
200 * @return string[] | |
201 * Enabled plugins CKEditor CSS files, with plugin IDs as keys and CSS file | |
202 * paths relative to the Drupal root (as implemented by getCssFiles()) as | |
203 * values. | |
204 * | |
205 * @see \Drupal\ckeditor\CKEditorPluginCssInterface::getCssFiles() | |
206 */ | |
207 public function getCssFiles(Editor $editor) { | |
208 $enabled_plugins = array_keys($this->getEnabledPluginFiles($editor, TRUE)); | |
209 $css_files = []; | |
210 | |
211 foreach ($enabled_plugins as $plugin_id) { | |
212 $plugin = $this->createInstance($plugin_id); | |
213 if ($plugin instanceof CKEditorPluginCssInterface) { | |
214 $css_files[$plugin_id] = $plugin->getCssFiles($editor); | |
215 } | |
216 } | |
217 | |
218 return $css_files; | |
219 } | |
220 | |
221 } |