Completed
Pull Request — master (#340)
by Maximilian
63:15
created

CKEditorRenderer::renderJsPath()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

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