Completed
Push — master ( da7c22...9abae1 )
by Eric
04:09
created

CKEditorHelper::fixUrl()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 10
rs 9.4286
cc 2
eloc 5
nc 2
nop 1
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\Templating;
13
14
use Ivory\JsonBuilder\JsonBuilder;
15
use Symfony\Component\DependencyInjection\ContainerInterface;
16
use Symfony\Component\Templating\Helper\Helper;
17
18
/**
19
 * CKEditor helper.
20
 *
21
 * @author GeLo <[email protected]>
22
 * @author Adam Misiorny <[email protected]>
23
 */
24
class CKEditorHelper extends Helper
25
{
26
    /** @var \Ivory\JsonBuilder\JsonBuilder */
27
    private $jsonBuilder;
28
29
    /** @var \Symfony\Component\DependencyInjection\ContainerInterface */
30
    private $container;
31
32
    /**
33
     * Creates a CKEditor template helper.
34
     *
35
     * @param \Symfony\Component\DependencyInjection\ContainerInterface $container The container.
36
     */
37
    public function __construct(ContainerInterface $container)
38
    {
39
        $this->jsonBuilder = new JsonBuilder();
40
        $this->container = $container;
41
    }
42
43
    /**
44
     * Renders the base path.
45
     *
46
     * @param string $basePath The base path.
47
     *
48
     * @return string The rendered base path.
49
     */
50
    public function renderBasePath($basePath)
51
    {
52
        return $this->fixPath($this->fixUrl($basePath));
53
    }
54
55
    /**
56
     * Renders the js path.
57
     *
58
     * @param string $jsPath The js path.
59
     *
60
     * @return string The rendered js path.
61
     */
62
    public function renderJsPath($jsPath)
63
    {
64
        return $this->fixUrl($jsPath);
65
    }
66
67
    /**
68
     * Renders the widget.
69
     *
70
     * @param string $id      The identifier.
71
     * @param array  $config  The config.
72
     * @param array  $options The options.
73
     *
74
     * The available options are:
75
     *  - auto_inline: boolean
76
     *  - inline: boolean
77
     *  - input_sync: boolean
78
     *
79
     * @return string The rendered widget.
80
     */
81
    public function renderWidget($id, array $config, array $options = array())
82
    {
83
        $config = $this->fixConfigLanguage($config);
84
        $config = $this->fixConfigContentsCss($config);
85
        $config = $this->fixConfigFilebrowsers($config);
86
87
        $this->jsonBuilder
88
            ->reset()
89
            ->setValues($config);
90
91
        $this->fixConfigEscapedValues($config);
92
93
        $autoInline = isset($options['auto_inline']) && !$options['auto_inline']
94
            ? 'CKEDITOR.disableAutoInline = true;'.PHP_EOL
95
            : null;
96
97
        $widget = sprintf(
98
            'CKEDITOR.%s("%s", %s);',
99
            isset($options['inline']) && $options['inline'] ? 'inline' : 'replace',
100
            $id,
101
            $this->fixConfigConstants($this->jsonBuilder->build())
102
        );
103
104
        if (isset($options['input_sync']) && $options['input_sync']) {
105
            $variable = 'ivory_ckeditor_'.$id;
106
            $widget = 'var '.$variable.' = '.$widget.PHP_EOL;
107
108
            return $autoInline.$widget.$variable.'.on(\'change\', function() { '.$variable.'.updateElement(); });';
109
        }
110
111
        return $autoInline.$widget;
112
    }
113
114
    /**
115
     * Renders the destroy.
116
     *
117
     * @param string $id The identifier.
118
     *
119
     * @return string The rendered destroy.
120
     */
121
    public function renderDestroy($id)
122
    {
123
        return sprintf('if (CKEDITOR.instances["%s"]) { delete CKEDITOR.instances["%s"]; }', $id, $id);
124
    }
125
126
    /**
127
     * Renders a plugin.
128
     *
129
     * @param string $name   The name.
130
     * @param array  $plugin The plugin.
131
     *
132
     * @return string The rendered plugin.
133
     */
134
    public function renderPlugin($name, array $plugin)
135
    {
136
        return sprintf(
137
            'CKEDITOR.plugins.addExternal("%s", "%s", "%s");',
138
            $name,
139
            $this->fixPath($this->fixUrl($plugin['path'])),
140
            $plugin['filename']
141
        );
142
    }
143
144
    /**
145
     * Renders a styles set.
146
     *
147
     * @param string $name      The name
148
     * @param array  $stylesSet The style set.
149
     *
150
     * @return string The rendered style set.
151
     */
152
    public function renderStylesSet($name, array $stylesSet)
153
    {
154
        $this->jsonBuilder
155
            ->reset()
156
            ->setValues($stylesSet);
157
158
        return sprintf(
159
            'if (CKEDITOR.stylesSet.get("%s") === null) { CKEDITOR.stylesSet.add("%s", %s); }',
160
            $name,
161
            $name,
162
            $this->jsonBuilder->build()
163
        );
164
    }
165
166
    /**
167
     * Renders a template.
168
     *
169
     * @param string $name     The template name.
170
     * @param array  $template The template.
171
     *
172
     * @return string The rendered template.
173
     */
174
    public function renderTemplate($name, array $template)
175
    {
176
        if (isset($template['imagesPath'])) {
177
            $template['imagesPath'] = $this->fixPath($this->fixUrl($template['imagesPath']));
178
        }
179
180
        $this->jsonBuilder
181
            ->reset()
182
            ->setValues($template);
183
184
        return sprintf('CKEDITOR.addTemplates("%s", %s);', $name, $this->jsonBuilder->build());
185
    }
186
187
    /**
188
     * {@inheritdoc}
189
     */
190
    public function getName()
191
    {
192
        return 'ivory_ckeditor';
193
    }
194
195
    /**
196
     * Fixes the config language.
197
     *
198
     * @param array $config The config.
199
     *
200
     * @return array The fixed config.
201
     */
202
    protected function fixConfigLanguage(array $config)
203
    {
204
        if (isset($config['language'])) {
205
            $config['language'] = strtolower(str_replace('_', '-', $config['language']));
206
        }
207
208
        return $config;
209
    }
210
211
    /**
212
     * Fixes the config contents css.
213
     *
214
     * @param array $config The config.
215
     *
216
     * @return array The fixed config.
217
     */
218
    private function fixConfigContentsCss(array $config)
219
    {
220
        if (isset($config['contentsCss'])) {
221
            $cssContents = (array) $config['contentsCss'];
222
223
            $config['contentsCss'] = array();
224
            foreach ($cssContents as $cssContent) {
225
                $config['contentsCss'][] = $this->fixPath($this->fixUrl($cssContent));
226
            }
227
        }
228
229
        return $config;
230
    }
231
232
    /**
233
     * Fixes the config filebrowsers.
234
     *
235
     * @param array $config The config.
236
     *
237
     * @return array The fixed config.
238
     */
239
    private function fixConfigFilebrowsers(array $config)
240
    {
241
        $keys = array(
242
            'Browse',
243
            'FlashBrowse',
244
            'ImageBrowse',
245
            'ImageBrowseLink',
246
            'Upload',
247
            'FlashUpload',
248
            'ImageUpload',
249
        );
250
251
        foreach ($keys as $key) {
252
            $fileBrowserKey = 'filebrowser'.$key;
253
            $handler = $fileBrowserKey.'Handler';
254
            $url = $fileBrowserKey.'Url';
255
            $route = $fileBrowserKey.'Route';
256
            $routeParameters = $fileBrowserKey.'RouteParameters';
257
            $routeAbsolute = $fileBrowserKey.'RouteAbsolute';
258
259
            if (isset($config[$handler])) {
260
                $config[$url] = $config[$handler]($this->getRouter());
261
            } elseif (isset($config[$route])) {
262
                $config[$url] = $this->getRouter()->generate(
263
                    $config[$route],
264
                    isset($config[$routeParameters]) ? $config[$routeParameters] : array(),
265
                    isset($config[$routeAbsolute]) ? $config[$routeAbsolute] : false
266
                );
267
            }
268
269
            unset($config[$handler]);
270
            unset($config[$route]);
271
            unset($config[$routeParameters]);
272
            unset($config[$routeAbsolute]);
273
        }
274
275
        return $config;
276
    }
277
278
    /**
279
     * Fixes the config escaped values and sets them on the json builder.
280
     *
281
     * @param array $config The config.
282
     */
283
    private function fixConfigEscapedValues(array $config)
284
    {
285
        if (isset($config['protectedSource'])) {
286
            foreach ($config['protectedSource'] as $key => $value) {
287
                $this->jsonBuilder->setValue(sprintf('[protectedSource][%s]', $key), $value, false);
288
            }
289
        }
290
291
        $escapedValueKeys = array(
292
            'stylesheetParser_skipSelectors',
293
            'stylesheetParser_validSelectors',
294
        );
295
296
        foreach ($escapedValueKeys as $escapedValueKey) {
297
            if (isset($config[$escapedValueKey])) {
298
                $this->jsonBuilder->setValue(sprintf('[%s]', $escapedValueKey), $config[$escapedValueKey], false);
299
            }
300
        }
301
    }
302
303
    /**
304
     * Fixes the config constants.
305
     *
306
     * @param string $json The json config.
307
     *
308
     * @return string The fixed config.
309
     */
310
    private function fixConfigConstants($json)
311
    {
312
        return preg_replace('/"(CKEDITOR\.[A-Z_]+)"/', '$1', $json);
313
    }
314
315
    /**
316
     * Fixes a path.
317
     *
318
     * @param string $path The path.
319
     *
320
     * @return string The fixed path.
321
     */
322
    private function fixPath($path)
323
    {
324
        if (($position = strpos($path, '?')) !== false) {
325
            return substr($path, 0, $position);
326
        }
327
328
        return $path;
329
    }
330
331
    /**
332
     * Fixes an url.
333
     *
334
     * @param string $url The url.
335
     *
336
     * @return string The fixed url.
337
     */
338
    private function fixUrl($url)
339
    {
340
        $assetsHelper = $this->getAssetsHelper();
341
342
        if ($assetsHelper !== null) {
343
            $url = $assetsHelper->getUrl($url);
344
        }
345
346
        return $url;
347
    }
348
349
    /**
350
     * Gets the assets helper.
351
     *
352
     * @return \Symfony\Component\Asset\Packages|\Symfony\Component\Templating\Helper\CoreAssetsHelper|null The assets helper.
353
     */
354
    private function getAssetsHelper()
355
    {
356
        return $this->container->get('assets.packages', ContainerInterface::NULL_ON_INVALID_REFERENCE);
357
    }
358
359
    /**
360
     * Gets the router.
361
     *
362
     * @return \Symfony\Component\Routing\RouterInterface The router.
363
     */
364
    private function getRouter()
365
    {
366
        return $this->container->get('router');
367
    }
368
}
369