Completed
Push — master ( cc8cfb...20053a )
by Eric
08:12
created

CKEditorRenderer::getTemplating()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

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