Completed
Pull Request — master (#342)
by Piotr
61:42
created

CKEditorRenderer::getLanguage()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 10
ccs 6
cts 6
cp 1
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 5
nc 3
nop 0
crap 3
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\Request;
17
use Symfony\Component\HttpFoundation\RequestStack;
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 RouterInterface
34
     */
35 790
    private $router;
36
37 790
    /**
38 790
     * @var Packages
39
     */
40
    private $packages;
41
42
    /**
43 100
     * @var EngineInterface
44
     */
45 100
    private $templating;
46
47
    public function __construct(
48
        JsonBuilder $jsonBuilder,
49
        RouterInterface $router,
50
        RequestStack $requestStack,
51 90
        Packages $packages = null,
52
        EngineInterface $templating = null,
53 90
        $locale = null
54
    ) {
55
        $this->jsonBuilder = $jsonBuilder;
56
        $this->router = $router;
57
        $this->packages = $packages;
58
        $this->templating = $templating;
59 610
        $requestLocale = $requestStack->getMasterRequest()->getLocale();
60
        $this->locale = $requestLocale ? $requestLocale : $locale;
0 ignored issues
show
Bug introduced by
The property locale does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

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