Completed
Push — language ( f1bdee )
by Eric
08:01
created

CKEditorRenderer::getRequest()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 10
rs 9.4285
cc 3
eloc 5
nc 3
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']) && ($language = $this->getLanguage()) !== null) {
173
            $config['language'] = $language;
174
        }
175
176
        if (isset($config['language'])) {
177
            $config['language'] = strtolower(str_replace('_', '-', $config['language']));
178
        }
179
180
        return $config;
181
    }
182
183
    /**
184
     * Fixes the config contents css.
185
     *
186
     * @param array $config The config.
187
     *
188
     * @return array The fixed config.
189
     */
190
    private function fixConfigContentsCss(array $config)
191
    {
192
        if (isset($config['contentsCss'])) {
193
            $cssContents = (array) $config['contentsCss'];
194
195
            $config['contentsCss'] = array();
196
            foreach ($cssContents as $cssContent) {
197
                $config['contentsCss'][] = $this->fixPath($this->fixUrl($cssContent));
198
            }
199
        }
200
201
        return $config;
202
    }
203
204
    /**
205
     * Fixes the config filebrowsers.
206
     *
207
     * @param array $config       The config.
208
     * @param array $filebrowsers The filebrowsers.
209
     *
210
     * @return array The fixed config.
211
     */
212
    private function fixConfigFilebrowsers(array $config, array $filebrowsers)
213
    {
214
        $filebrowsers = array_unique(array_merge(array(
215
            'Browse',
216
            'FlashBrowse',
217
            'ImageBrowse',
218
            'ImageBrowseLink',
219
            'Upload',
220
            'FlashUpload',
221
            'ImageUpload',
222
        ), $filebrowsers));
223
224
        foreach ($filebrowsers as $filebrowser) {
225
            $fileBrowserKey = 'filebrowser'.$filebrowser;
226
            $handler = $fileBrowserKey.'Handler';
227
            $url = $fileBrowserKey.'Url';
228
            $route = $fileBrowserKey.'Route';
229
            $routeParameters = $fileBrowserKey.'RouteParameters';
230
            $routeAbsolute = $fileBrowserKey.'RouteAbsolute';
231
232
            if (isset($config[$handler])) {
233
                $config[$url] = $config[$handler]($this->getRouter());
234
            } elseif (isset($config[$route])) {
235
                $config[$url] = $this->getRouter()->generate(
236
                    $config[$route],
237
                    isset($config[$routeParameters]) ? $config[$routeParameters] : array(),
238
                    isset($config[$routeAbsolute])
239
                        ? $config[$routeAbsolute]
240
                        : (
241
                            defined('Symfony\Component\Routing\Generator\UrlGeneratorInterface::ABSOLUTE_PATH')
242
                                ? UrlGeneratorInterface::ABSOLUTE_PATH
243
                                : false
244
                        )
245
                );
246
            }
247
248
            unset($config[$handler]);
249
            unset($config[$route]);
250
            unset($config[$routeParameters]);
251
            unset($config[$routeAbsolute]);
252
        }
253
254
        return $config;
255
    }
256
257
    /**
258
     * Fixes the config escaped values and sets them on the json builder.
259
     *
260
     * @param array $config The config.
261
     */
262
    private function fixConfigEscapedValues(array $config)
263
    {
264
        if (isset($config['protectedSource'])) {
265
            foreach ($config['protectedSource'] as $key => $value) {
266
                $this->jsonBuilder->setValue(sprintf('[protectedSource][%s]', $key), $value, false);
267
            }
268
        }
269
270
        $escapedValueKeys = array(
271
            'stylesheetParser_skipSelectors',
272
            'stylesheetParser_validSelectors',
273
        );
274
275
        foreach ($escapedValueKeys as $escapedValueKey) {
276
            if (isset($config[$escapedValueKey])) {
277
                $this->jsonBuilder->setValue(sprintf('[%s]', $escapedValueKey), $config[$escapedValueKey], false);
278
            }
279
        }
280
    }
281
282
    /**
283
     * Fixes the config constants.
284
     *
285
     * @param string $json The json config.
286
     *
287
     * @return string The fixed config.
288
     */
289
    private function fixConfigConstants($json)
290
    {
291
        return preg_replace('/"(CKEDITOR\.[A-Z_]+)"/', '$1', $json);
292
    }
293
294
    /**
295
     * Fixes a path.
296
     *
297
     * @param string $path The path.
298
     *
299
     * @return string The fixed path.
300
     */
301
    private function fixPath($path)
302
    {
303
        if (($position = strpos($path, '?')) !== false) {
304
            return substr($path, 0, $position);
305
        }
306
307
        return $path;
308
    }
309
310
    /**
311
     * Fixes an url.
312
     *
313
     * @param string $url The url.
314
     *
315
     * @return string The fixed url.
316
     */
317
    private function fixUrl($url)
318
    {
319
        $assetsHelper = $this->getAssetsHelper();
320
321
        if ($assetsHelper !== null) {
322
            $url = $assetsHelper->getUrl($url);
323
        }
324
325
        return $url;
326
    }
327
328
    /**
329
     * Gets the locale.
330
     *
331
     * @return string|null The locale.
332
     */
333
    private function getLanguage()
334
    {
335
        if (($request = $this->getRequest()) !== null) {
336
            return $request->getLocale();
337
        }
338
339
        if ($this->container->hasParameter($parameter = 'locale')) {
340
            return $this->container->getParameter($parameter);
341
        }
342
    }
343
344
    /**
345
     * Gets the request.
346
     *
347
     * @return \Symfony\Component\HttpFoundation\Request The request.
348
     */
349
    private function getRequest()
350
    {
351
        if ($this->container->has($service = 'request_stack')) {
352
            return $this->container->get($service)->getMasterRequest();
353
        }
354
355
        if ($this->container->has($service = 'request')) {
356
            return $this->container->get($service);
357
        }
358
    }
359
360
    /**
361
     * Gets the templating engine.
362
     *
363
     * @return \Symfony\Component\Templating\EngineInterface|\Twig_Environment The templating engine.
364
     */
365
    private function getTemplating()
366
    {
367
        if ($this->container->has($templating = 'templating')) {
368
            return $this->container->get($templating);
369
        }
370
371
        return $this->container->get('twig');
372
    }
373
374
    /**
375
     * Gets the assets helper.
376
     *
377
     * @return \Symfony\Component\Asset\Packages|\Symfony\Component\Templating\Helper\CoreAssetsHelper|null The assets helper.
378
     */
379
    private function getAssetsHelper()
380
    {
381
        return $this->container->get('assets.packages', ContainerInterface::NULL_ON_INVALID_REFERENCE);
382
    }
383
384
    /**
385
     * Gets the router.
386
     *
387
     * @return \Symfony\Component\Routing\RouterInterface The router.
388
     */
389
    private function getRouter()
390
    {
391
        return $this->container->get('router');
392
    }
393
}
394