1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/* |
4
|
|
|
* This file is part of the Ivory CKEditor package. |
5
|
|
|
* |
6
|
|
|
* (c) Eric GELOEN <[email protected]> |
7
|
|
|
* |
8
|
|
|
* For the full copyright and license information, please read the LICENSE |
9
|
|
|
* file that was distributed with this source code. |
10
|
|
|
*/ |
11
|
|
|
|
12
|
|
|
namespace Ivory\CKEditorBundle\DependencyInjection; |
13
|
|
|
|
14
|
|
|
use Ivory\CKEditorBundle\Exception\DependencyInjectionException; |
15
|
|
|
use Symfony\Component\Config\FileLocator; |
16
|
|
|
use Symfony\Component\DependencyInjection\ContainerBuilder; |
17
|
|
|
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; |
18
|
|
|
use Symfony\Component\HttpKernel\DependencyInjection\ConfigurableExtension; |
19
|
|
|
use Symfony\Component\HttpKernel\Kernel; |
20
|
|
|
|
21
|
|
|
/** |
22
|
|
|
* Ivory CKEditor extension. |
23
|
|
|
* |
24
|
|
|
* @author GeLo <[email protected]> |
25
|
|
|
*/ |
26
|
|
|
class IvoryCKEditorExtension extends ConfigurableExtension |
27
|
|
|
{ |
28
|
|
|
/** |
29
|
|
|
* {@inheritdoc} |
30
|
|
|
*/ |
31
|
|
|
protected function loadInternal(array $config, ContainerBuilder $container) |
32
|
|
|
{ |
33
|
|
|
$loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); |
34
|
|
|
foreach (array('form', 'templating', 'twig') as $service) { |
35
|
|
|
$loader->load($service.'.xml'); |
36
|
|
|
} |
37
|
|
|
|
38
|
|
|
$this->registerConfig($config, $container); |
39
|
|
|
|
40
|
|
|
if (!isset($config['enable']) || $config['enable']) { |
41
|
|
|
$this->registerConfigs($config, $container); |
42
|
|
|
$this->registerPlugins($config, $container); |
43
|
|
|
$this->registerStylesSet($config, $container); |
44
|
|
|
$this->registerTemplates($config, $container); |
45
|
|
|
} |
46
|
|
|
|
47
|
|
|
if (Kernel::VERSION_ID < 30000) { |
48
|
|
|
$container->getDefinition('ivory_ck_editor.form.type') |
49
|
|
|
->clearTag('form.type') |
50
|
|
|
->addTag('form.type', array('alias' => 'ckeditor')); |
51
|
|
|
} |
52
|
|
|
} |
53
|
|
|
|
54
|
|
|
/** |
55
|
|
|
* Registers the CKEditor config. |
56
|
|
|
* |
57
|
|
|
* @param array $config The CKEditor configuration |
58
|
|
|
* @param \Symfony\Component\DependencyInjection\ContainerBuilder $container The container. |
59
|
|
|
*/ |
60
|
|
|
private function registerConfig(array $config, ContainerBuilder $container) |
61
|
|
|
{ |
62
|
|
|
$formType = $container->getDefinition('ivory_ck_editor.form.type'); |
63
|
|
|
|
64
|
|
|
if (isset($config['enable'])) { |
65
|
|
|
$formType->addMethodCall('isEnable', array($config['enable'])); |
66
|
|
|
} |
67
|
|
|
|
68
|
|
|
if (isset($config['auto_inline'])) { |
69
|
|
|
$formType->addMethodCall('isAutoInline', array($config['auto_inline'])); |
70
|
|
|
} |
71
|
|
|
|
72
|
|
|
if (isset($config['inline'])) { |
73
|
|
|
$formType->addMethodCall('isInline', array($config['inline'])); |
74
|
|
|
} |
75
|
|
|
|
76
|
|
|
if (isset($config['autoload'])) { |
77
|
|
|
$formType->addMethodCall('isAutoload', array($config['autoload'])); |
78
|
|
|
} |
79
|
|
|
|
80
|
|
|
if (isset($config['jquery'])) { |
81
|
|
|
$formType->addMethodCall('useJquery', array($config['jquery'])); |
82
|
|
|
} |
83
|
|
|
|
84
|
|
|
if (isset($config['input_sync'])) { |
85
|
|
|
$formType->addMethodCall('isInputSync', array($config['input_sync'])); |
86
|
|
|
} |
87
|
|
|
|
88
|
|
|
if (isset($config['base_path'])) { |
89
|
|
|
$formType->addMethodCall('setBasePath', array($config['base_path'])); |
90
|
|
|
} |
91
|
|
|
|
92
|
|
|
if (isset($config['js_path'])) { |
93
|
|
|
$formType->addMethodCall('setJsPath', array($config['js_path'])); |
94
|
|
|
} |
95
|
|
|
|
96
|
|
|
if (isset($config['jquery_path'])) { |
97
|
|
|
$formType->addMethodCall('setJqueryPath', array($config['jquery_path'])); |
98
|
|
|
} |
99
|
|
|
} |
100
|
|
|
|
101
|
|
|
/** |
102
|
|
|
* Registers the CKEditor configs. |
103
|
|
|
* |
104
|
|
|
* @param array $config The CKEditor configuration. |
105
|
|
|
* @param \Symfony\Component\DependencyInjection\ContainerBuilder $container The container. |
106
|
|
|
* |
107
|
|
|
* @throws \Ivory\CKEditorBundle\Exception\DependencyInjectionException If the default config does not exist. |
108
|
|
|
*/ |
109
|
|
|
private function registerConfigs(array $config, ContainerBuilder $container) |
110
|
|
|
{ |
111
|
|
|
if (empty($config['configs'])) { |
112
|
|
|
return; |
113
|
|
|
} |
114
|
|
|
|
115
|
|
|
$config = $this->mergeToolbars($config); |
116
|
|
|
|
117
|
|
|
$definition = $container->getDefinition('ivory_ck_editor.config_manager'); |
118
|
|
|
foreach ($config['configs'] as $name => $configuration) { |
119
|
|
|
$definition->addMethodCall('setConfig', array($name, $configuration)); |
120
|
|
|
} |
121
|
|
|
|
122
|
|
|
if (isset($config['default_config'])) { |
123
|
|
|
if (!isset($config['configs'][$config['default_config']])) { |
124
|
|
|
throw DependencyInjectionException::invalidDefaultConfig($config['default_config']); |
125
|
|
|
} |
126
|
|
|
|
127
|
|
|
$definition->addMethodCall('setDefaultConfig', array($config['default_config'])); |
128
|
|
|
} |
129
|
|
|
} |
130
|
|
|
|
131
|
|
|
/** |
132
|
|
|
* Registers the CKEditor plugins. |
133
|
|
|
* |
134
|
|
|
* @param array $config The CKEditor configuration. |
135
|
|
|
* @param \Symfony\Component\DependencyInjection\ContainerBuilder $container The container. |
136
|
|
|
*/ |
137
|
|
|
private function registerPlugins(array $config, ContainerBuilder $container) |
138
|
|
|
{ |
139
|
|
|
if (empty($config['plugins'])) { |
140
|
|
|
return; |
141
|
|
|
} |
142
|
|
|
|
143
|
|
|
$definition = $container->getDefinition('ivory_ck_editor.plugin_manager'); |
144
|
|
|
|
145
|
|
|
foreach ($config['plugins'] as $name => $plugin) { |
146
|
|
|
$definition->addMethodCall('setPlugin', array($name, $plugin)); |
147
|
|
|
} |
148
|
|
|
} |
149
|
|
|
|
150
|
|
|
/** |
151
|
|
|
* Registers the CKEditor styles set. |
152
|
|
|
* |
153
|
|
|
* @param array $config The CKEditor configuration. |
154
|
|
|
* @param \Symfony\Component\DependencyInjection\ContainerBuilder $container The container. |
155
|
|
|
*/ |
156
|
|
View Code Duplication |
private function registerStylesSet(array $config, ContainerBuilder $container) |
|
|
|
|
157
|
|
|
{ |
158
|
|
|
if (empty($config['styles'])) { |
159
|
|
|
return; |
160
|
|
|
} |
161
|
|
|
|
162
|
|
|
$definition = $container->getDefinition('ivory_ck_editor.styles_set_manager'); |
163
|
|
|
|
164
|
|
|
foreach ($config['styles'] as $name => $stylesSet) { |
165
|
|
|
$definition->addMethodCall('setStylesSet', array($name, $this->fixStylesSet($stylesSet))); |
166
|
|
|
} |
167
|
|
|
} |
168
|
|
|
|
169
|
|
|
/** |
170
|
|
|
* Registers the CKEditor templates. |
171
|
|
|
* |
172
|
|
|
* @param array $config The CKEditor configuration. |
173
|
|
|
* @param \Symfony\Component\DependencyInjection\ContainerBuilder $container The container. |
174
|
|
|
*/ |
175
|
|
View Code Duplication |
private function registerTemplates(array $config, ContainerBuilder $container) |
|
|
|
|
176
|
|
|
{ |
177
|
|
|
if (empty($config['templates'])) { |
178
|
|
|
return; |
179
|
|
|
} |
180
|
|
|
|
181
|
|
|
$definition = $container->getDefinition('ivory_ck_editor.template_manager'); |
182
|
|
|
|
183
|
|
|
foreach ($config['templates'] as $name => $template) { |
184
|
|
|
$definition->addMethodCall('setTemplate', array($name, $template)); |
185
|
|
|
} |
186
|
|
|
} |
187
|
|
|
|
188
|
|
|
/** |
189
|
|
|
* Merges the toolbars into the CKEditor configs. |
190
|
|
|
* |
191
|
|
|
* @param array $config The CKEditor configuration. |
192
|
|
|
* |
193
|
|
|
* @throws \Ivory\CKEditorBundle\Exception\DependencyInjectionException If a toolbar does not exist. |
194
|
|
|
* |
195
|
|
|
* @return array The CKEditor configuration with merged toolbars. |
196
|
|
|
*/ |
197
|
|
|
private function mergeToolbars(array $config) |
198
|
|
|
{ |
199
|
|
|
$resolvedToolbars = $this->resolveToolbars($config); |
200
|
|
|
unset($config['toolbars']); |
201
|
|
|
|
202
|
|
|
foreach ($config['configs'] as $name => $configuration) { |
203
|
|
|
if (!isset($configuration['toolbar']) || !is_string($configuration['toolbar'])) { |
204
|
|
|
continue; |
205
|
|
|
} |
206
|
|
|
|
207
|
|
|
if (!isset($resolvedToolbars[$configuration['toolbar']])) { |
208
|
|
|
throw DependencyInjectionException::invalidToolbar($configuration['toolbar']); |
209
|
|
|
} |
210
|
|
|
|
211
|
|
|
$config['configs'][$name]['toolbar'] = $resolvedToolbars[$configuration['toolbar']]; |
212
|
|
|
} |
213
|
|
|
|
214
|
|
|
return $config; |
215
|
|
|
} |
216
|
|
|
|
217
|
|
|
/** |
218
|
|
|
* Resolves the CKEditor toolbars. |
219
|
|
|
* |
220
|
|
|
* @param array $config The CKEditor configuration. |
221
|
|
|
* |
222
|
|
|
* @return array The resolved CKEditor toolbars. |
223
|
|
|
*/ |
224
|
|
|
private function resolveToolbars(array $config) |
225
|
|
|
{ |
226
|
|
|
$resolvedToolbars = array(); |
227
|
|
|
|
228
|
|
|
foreach ($config['toolbars']['configs'] as $name => $toolbar) { |
229
|
|
|
$resolvedToolbars[$name] = array(); |
230
|
|
|
|
231
|
|
|
foreach ($toolbar as $item) { |
232
|
|
|
$resolvedToolbars[$name][] = $this->resolveToolbarItem($item, $config['toolbars']['items']); |
233
|
|
|
} |
234
|
|
|
} |
235
|
|
|
|
236
|
|
|
return array_merge($this->getDefaultToolbars(), $resolvedToolbars); |
237
|
|
|
} |
238
|
|
|
|
239
|
|
|
/** |
240
|
|
|
* Resolves a CKEditor toolbar item. |
241
|
|
|
* |
242
|
|
|
* @param string|array $item The CKEditor item. |
243
|
|
|
* @param array $items The CKEditor items. |
244
|
|
|
* |
245
|
|
|
* @throws \Ivory\CKEditorBundle\Exception\DependencyInjectionException If the toolbar item does not exist. |
246
|
|
|
* |
247
|
|
|
* @return array|string The resolved CKEditor toolbar item. |
248
|
|
|
*/ |
249
|
|
|
private function resolveToolbarItem($item, array $items) |
250
|
|
|
{ |
251
|
|
|
if (is_string($item) && ($item[0] === '@')) { |
252
|
|
|
$itemName = substr($item, 1); |
253
|
|
|
|
254
|
|
|
if (!isset($items[$itemName])) { |
255
|
|
|
throw DependencyInjectionException::invalidToolbarItem($itemName); |
256
|
|
|
} |
257
|
|
|
|
258
|
|
|
return $items[$itemName]; |
259
|
|
|
} |
260
|
|
|
|
261
|
|
|
return $item; |
262
|
|
|
} |
263
|
|
|
|
264
|
|
|
/** |
265
|
|
|
* Fixes the CKEditor styles set. |
266
|
|
|
* |
267
|
|
|
* @param array $stylesSet The CKEditor styles set. |
268
|
|
|
* |
269
|
|
|
* @return array The fixed CKEditor styles set. |
270
|
|
|
*/ |
271
|
|
|
private function fixStylesSet(array $stylesSet) |
272
|
|
|
{ |
273
|
|
|
foreach ($stylesSet as &$value) { |
274
|
|
|
$value = array_filter($value); |
275
|
|
|
} |
276
|
|
|
|
277
|
|
|
return $stylesSet; |
278
|
|
|
} |
279
|
|
|
|
280
|
|
|
/** |
281
|
|
|
* Gets the default CKEditor toolbars. |
282
|
|
|
* |
283
|
|
|
* @return array The default CKEditor toolbars. |
284
|
|
|
*/ |
285
|
|
|
private function getDefaultToolbars() |
286
|
|
|
{ |
287
|
|
|
return array( |
288
|
|
|
'full' => $this->getFullToolbar(), |
289
|
|
|
'standard' => $this->getStandardToolbar(), |
290
|
|
|
'basic' => $this->getBasicToolbar(), |
291
|
|
|
); |
292
|
|
|
} |
293
|
|
|
|
294
|
|
|
/** |
295
|
|
|
* Gets the full CKEditor toolbar. |
296
|
|
|
* |
297
|
|
|
* @return array The full CKEditor toolbar. |
298
|
|
|
*/ |
299
|
|
|
private function getFullToolbar() |
300
|
|
|
{ |
301
|
|
|
return array( |
302
|
|
|
array('Source', '-', 'NewPage', 'Preview', 'Print', '-', 'Templates'), |
303
|
|
|
array('Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord', '-', 'Undo', 'Redo'), |
304
|
|
|
array('Find', 'Replace', '-', 'SelectAll', '-', 'Scayt'), |
305
|
|
|
array( |
306
|
|
|
'Form', 'Checkbox', 'Radio', 'TextField', 'Textarea', 'SelectField', 'Button', 'ImageButton', |
307
|
|
|
'HiddenField', |
308
|
|
|
), |
309
|
|
|
'/', |
310
|
|
|
array('Bold', 'Italic', 'Underline', 'Strike', 'Subscript', 'Superscript', '-', 'RemoveFormat'), |
311
|
|
|
array( |
312
|
|
|
'NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', '-', 'Blockquote', 'CreateDiv', '-', |
313
|
|
|
'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock', '-', 'BidiLtr', 'BidiRtl', |
314
|
|
|
), |
315
|
|
|
array('Link', 'Unlink', 'Anchor'), |
316
|
|
|
array('Image', 'FLash', 'Table', 'HorizontalRule', 'SpecialChar', 'Smiley', 'PageBreak', 'Iframe'), |
317
|
|
|
'/', |
318
|
|
|
array('Styles', 'Format', 'Font', 'FontSize', 'TextColor', 'BGColor'), |
319
|
|
|
array('Maximize', 'ShowBlocks'), |
320
|
|
|
array('About'), |
321
|
|
|
); |
322
|
|
|
} |
323
|
|
|
|
324
|
|
|
/** |
325
|
|
|
* Gets the standard CKEditor toolbar. |
326
|
|
|
* |
327
|
|
|
* @return array The standard CKEditor toolbar. |
328
|
|
|
*/ |
329
|
|
|
private function getStandardToolbar() |
330
|
|
|
{ |
331
|
|
|
return array( |
332
|
|
|
array('Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord', '-', 'Undo', 'Redo'), |
333
|
|
|
array('Scayt'), |
334
|
|
|
array('Link', 'Unlink', 'Anchor'), |
335
|
|
|
array('Image', 'Table', 'HorizontalRule', 'SpecialChar'), |
336
|
|
|
array('Maximize'), |
337
|
|
|
array('Source'), |
338
|
|
|
'/', |
339
|
|
|
array('Bold', 'Italic', 'Strike', '-', 'RemoveFormat'), |
340
|
|
|
array('NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', '-', 'Blockquote'), |
341
|
|
|
array('Styles', 'Format', 'About'), |
342
|
|
|
); |
343
|
|
|
} |
344
|
|
|
|
345
|
|
|
/** |
346
|
|
|
* Gets the basic CKEditor toolbar. |
347
|
|
|
* |
348
|
|
|
* @return array The basic CKEditor toolbar. |
349
|
|
|
*/ |
350
|
|
|
private function getBasicToolbar() |
351
|
|
|
{ |
352
|
|
|
return array( |
353
|
|
|
array('Bold', 'Italic'), |
354
|
|
|
array('NumberedList', 'BulletedList', '-', 'Outdent', 'Indent'), |
355
|
|
|
array('Link', 'Unlink'), |
356
|
|
|
array('About'), |
357
|
|
|
); |
358
|
|
|
} |
359
|
|
|
} |
360
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.