Passed
Pull Request — master (#5690)
by
unknown
07:24
created

CkEditor::getImagePicker()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 1
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
/* For licensing terms, see /license.txt */
6
7
namespace Chamilo\CoreBundle\Component\Editor\CkEditor;
8
9
use Chamilo\CoreBundle\Component\Editor\Editor;
10
use Chamilo\CoreBundle\Entity\Course;
11
use Chamilo\CoreBundle\Entity\SystemTemplate;
12
use Chamilo\CoreBundle\Entity\Templates;
13
use Chamilo\CoreBundle\Framework\Container;
14
use Database;
15
16
class CkEditor extends Editor
17
{
18
    /**
19
     * Return the HTML code required to run editor.
20
     *
21
     * @param string $value
22
     */
23
    public function createHtml($value): string
24
    {
25
        $html = '<textarea id="'.$this->getTextareaId().'" name="'.$this->getName().'" >
26
                 '.$value.'
27
                 </textarea>';
28
        $html .= $this->editorReplace();
29
30
        return $html;
31
    }
32
33
    /**
34
     * Return the HTML code required to run editor.
35
     *
36
     * @param string $value
37
     */
38
    public function createHtmlStyle($value): string
39
    {
40
        $style = '';
41
        $value = trim($value);
42
43
        if ('' === $value || '<html><head><title></title></head><body></body></html>' === $value) {
44
            $style = api_get_bootstrap_and_font_awesome();
45
            $style .= Container::getThemeHelper()->getThemeAssetLinkTag('document.css');
46
        }
47
48
        $html = '<textarea id="'.$this->getTextareaId().'" name="'.$this->getName().'" >
49
                 '.$style.$value.'
50
                 </textarea>';
51
        $html .= $this->editorReplace();
52
53
        return $html;
54
    }
55
56
    public function editorReplace(): string
57
    {
58
        $toolbar = new Toolbar\Basic(
59
            $this->urlGenerator,
60
            $this->toolbarSet,
61
            $this->config,
62
            'CkEditor'
63
        );
64
65
        $config = $toolbar->getConfig();
66
        $config['selector'] = '#'.$this->getTextareaId();
67
        $javascript = $this->toJavascript($config);
68
69
        // it replaces [browser] by image picker callback
70
        $javascript = str_replace('"[browser]"', $this->getFileManagerPicker(), $javascript);
71
72
        return "<script>
73
            window.addEventListener('message', function(event) {
74
                // Check if the received message contains the URL data
75
                if (event.data.url) {
76
                    // Check if we are in an iframe
77
                    if (window.parent !== window) {
78
                        // Send the message to the parent window
79
                        window.parent.postMessage(event.data, '*');
80
                        // Access the callback function in the parent window
81
                        const parentWindow = window.parent.window[0].window;
82
                        if (parentWindow && parentWindow.tinyMCECallback) {
83
                            parentWindow.tinyMCECallback(event.data.url);
84
                            delete parentWindow.tinyMCECallback;
85
                        }
86
                    } else if (window.tinyMCECallback) {
87
                        // Handle the message in the main context
88
                        window.tinyMCECallback(event.data.url);
89
                        delete window.tinyMCECallback;
90
                    }
91
                }
92
            });
93
94
            document.addEventListener('DOMContentLoaded', function() {
95
                window.chEditors = window.chEditors || [];
96
                window.chEditors.push($javascript)
97
           });
98
           </script>";
99
    }
100
101
    /**
102
     * @param array $templates
103
     */
104
    public function formatTemplates($templates): string
105
    {
106
        if (empty($templates)) {
107
            return '';
108
        }
109
        $templateList = [];
110
        $cssTheme = api_get_path(WEB_CSS_PATH).'themes/'.api_get_visual_theme().'/';
111
        $search = ['{CSS_THEME}', '{IMG_DIR}', '{REL_PATH}', '{COURSE_DIR}', '{CSS}'];
112
        $replace = [
113
            $cssTheme,
114
            api_get_path(REL_CODE_PATH).'img/',
115
            api_get_path(REL_PATH),
116
            // api_get_path(REL_DEFAULT_COURSE_DOCUMENT_PATH),
117
            '',
118
        ];
119
120
        /** @var SystemTemplate $template */
121
        foreach ($templates as $template) {
122
            $image = $template->getImage();
123
            $image = !empty($image) ? $image : 'empty.gif';
124
125
            /*$image = $this->urlGenerator->generate(
126
                'get_document_template_action',
127
                array('file' => $image),
128
                UrlGenerator::ABSOLUTE_URL
129
            );*/
130
131
            $content = str_replace($search, $replace, $template->getContent());
132
133
            $templateList[] = [
134
                'title' => $this->translator->trans($template->getTitle()),
135
                'description' => $this->translator->trans($template->getComment()),
136
                'image' => $image,
137
                'html' => $content,
138
            ];
139
        }
140
141
        return json_encode($templateList);
142
    }
143
144
    /**
145
     * Get the templates in JSON format.
146
     *
147
     * @return false|string
148
     */
149
    public function simpleFormatTemplates()
150
    {
151
        $templates = $this->getEmptyTemplate();
152
153
        if (api_is_allowed_to_edit(false, true)) {
154
            $platformTemplates = $this->getPlatformTemplates();
155
            $templates = array_merge($templates, $platformTemplates);
156
        }
157
158
        $personalTemplates = $this->getPersonalTemplates();
159
        $templates = array_merge($templates, $personalTemplates);
160
161
        return json_encode($templates);
162
    }
163
164
    /**
165
     * Get a custom image picker.
166
     */
167
    private function getImagePicker(): string
168
    {
169
        return 'function (cb, value, meta) {
170
            var input = document.createElement("input");
171
            input.setAttribute("type", "file");
172
            input.setAttribute("accept", "image/*");
173
            input.onchange = function () {
174
                var file = this.files[0];
175
                var reader = new FileReader();
176
                reader.onload = function () {
177
                    var id = "blobid" + (new Date()).getTime();
178
                    var blobCache =  tinymce.activeEditor.editorUpload.blobCache;
179
                    var base64 = reader.result.split(",")[1];
180
                    var blobInfo = blobCache.create(id, file, base64);
181
                    blobCache.add(blobInfo);
182
                    cb(blobInfo.blobUri(), { title: file.name });
183
                };
184
                reader.readAsDataURL(file);
185
            };
186
            input.click();
187
        }';
188
    }
189
190
    /**
191
     * Generates a JavaScript function for TinyMCE file manager picker.
192
     *
193
     * @param bool $onlyPersonalfiles if true, only shows personal files
194
     *
195
     * @return string javaScript function as string
196
     */
197
    private function getFileManagerPicker($onlyPersonalfiles = true): string
198
    {
199
        $user = api_get_user_entity();
200
        $course = api_get_course_entity();
201
202
        if ($onlyPersonalfiles) {
203
            if (null !== $user) {
204
                $cidReqQuery = '';
205
                if (null !== $course) {
206
                    $parentResourceNodeId = $course->getResourceNode()->getId();
207
                    $cidReqQuery = '&'.api_get_cidreq().'&parentResourceNodeId='.$parentResourceNodeId;
208
                }
209
                $resourceNodeId = $user->getResourceNode()->getId();
210
                $url = api_get_path(WEB_PATH).'resources/filemanager/personal_list/'.$resourceNodeId.'?loadNode=1'.$cidReqQuery;
211
            }
212
        } else {
213
            if (null !== $course) {
214
                $resourceNodeId = $course->getResourceNode()->getId();
215
                $url = api_get_path(WEB_PATH).'resources/document/'.$resourceNodeId.'/manager?'.api_get_cidreq();
216
            } elseif (null !== $user) {
217
                $resourceNodeId = $user->getResourceNode()->getId();
218
                $url = api_get_path(WEB_PATH).'resources/filemanager/personal_list/'.$resourceNodeId.'?loadNode=1';
219
            }
220
        }
221
222
        if (!isset($url)) {
223
            return $this->getImagePicker();
224
        }
225
226
        return '
227
            function(cb, value, meta) {
228
                window.tinyMCECallback = cb;
229
                let fileType = meta.filetype;
230
                let fileManagerUrl = "'.$url.'";
231
232
                if (fileType === "image") {
233
                    fileManagerUrl += "&type=images";
234
                } else if (fileType === "file") {
235
                    fileManagerUrl += "&type=files";
236
                }
237
238
                tinymce.activeEditor.windowManager.openUrl({
239
                    title: "File Manager",
240
                    url: fileManagerUrl,
241
                    width: 980,
242
                    height: 600
243
                });
244
            }
245
        ';
246
    }
247
248
    /**
249
     * Get the empty template.
250
     */
251
    private function getEmptyTemplate(): array
252
    {
253
        return [
254
            [
255
                'title' => get_lang('Blank template'),
256
                'description' => null,
257
                'image' => api_get_path(WEB_PUBLIC_PATH).'img/template_thumb/empty.gif',
258
                'html' => '
259
                <!DOCYTPE html>
260
                <html>
261
                    <head>
262
                        <meta charset="'.api_get_system_encoding().'" />
263
                    </head>
264
                    <body  dir="'.api_get_text_direction().'">
265
                        <p>
266
                            <br/>
267
                        </p>
268
                    </body>
269
                    </html>
270
                </html>
271
            ',
272
            ],
273
        ];
274
    }
275
276
    /**
277
     * Get the platform templates.
278
     */
279
    private function getPlatformTemplates(): array
280
    {
281
        $entityManager = Database::getManager();
282
        $systemTemplates = $entityManager->getRepository(SystemTemplate::class)->findAll();
283
        $cssTheme = api_get_path(WEB_CSS_PATH).'themes/'.api_get_visual_theme().'/';
284
        $search = ['{CSS_THEME}', '{IMG_DIR}', '{REL_PATH}', '{COURSE_DIR}', '{CSS}'];
285
        $replace = [
286
            $cssTheme,
287
            api_get_path(REL_PATH).'public/img/',
288
            api_get_path(REL_PATH),
289
            api_get_path(REL_PATH).'public/img/document/',
290
            '',
291
        ];
292
293
        $templateList = [];
294
295
        foreach ($systemTemplates as $template) {
296
            $image = $template->getImage();
297
            $image = !empty($image) ? $image : 'empty.gif';
298
            $image = api_get_path(WEB_PUBLIC_PATH).'img/template_thumb/'.$image;
299
            $templateContent = $template->getContent();
300
            $content = str_replace($search, $replace, $templateContent);
301
302
            $templateList[] = [
303
                'title' => get_lang($template->getTitle()),
304
                'description' => get_lang($template->getComment()),
305
                'image' => $image,
306
                'html' => $content,
307
            ];
308
        }
309
310
        return $templateList;
311
    }
312
313
    /**
314
     * @param int $userId
315
     *
316
     * @return array
317
     */
318
    private function getPersonalTemplates($userId = 0)
319
    {
320
        if (empty($userId)) {
321
            $userId = api_get_user_id();
322
        }
323
324
        $entityManager = Database::getManager();
325
        $templatesRepo = $entityManager->getRepository(Templates::class);
326
        $user = api_get_user_entity($userId);
327
        $course = $entityManager->find(Course::class, api_get_course_int_id());
328
329
        if (!$user || !$course) {
330
            return [];
331
        }
332
333
        $courseTemplates = $templatesRepo->getCourseTemplates($course, $user);
334
        $templateList = [];
335
336
        foreach ($courseTemplates as $templateData) {
337
            $template = $templateData[0];
338
339
            $templateItem = [];
340
            $templateItem['title'] = $template->getTitle();
341
            $templateItem['description'] = $template->getDescription();
342
            $templateItem['image'] = api_get_path(WEB_PUBLIC_PATH).'img/template_thumb/noimage.gif';
343
            /*$templateItem['html'] = file_get_contents(api_get_path(SYS_COURSE_PATH)
344
                .$courseDirectory.'/document'.$templateData['path']);*/
345
346
            $image = $template->getImage();
347
            if (!empty($image)) {
348
                $templateItem['image'] = api_get_path(WEB_COURSE_PATH)
349
                    .$courseDirectory.'/upload/template_thumbnails/'.$template->getImage();
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $courseDirectory does not exist. Did you maybe mean $course?
Loading history...
350
            }
351
352
            $templateList[] = $templateItem;
353
        }
354
355
        return $templateList;
356
    }
357
}
358