Completed
Pull Request — master (#289)
by Eric
10:25 queued 04:01
created

CKEditorRenderer::fixUrl()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 2

Importance

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