Completed
Pull Request — master (#277)
by Eric
01:49
created

CKEditorRenderer::renderBasePath()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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