Completed
Pull Request — master (#340)
by Maximilian
61:00
created

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