FormCKEdit   F
last analyzed

Complexity

Total Complexity 68

Size/Duplication

Total Lines 555
Duplicated Lines 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
eloc 220
c 4
b 0
f 0
dl 0
loc 555
rs 2.96
wmc 68

29 Methods

Rating   Name   Duplication   Size   Complexity  
A readAdditionalXML() 0 5 1
A addTemplateSelect() 0 4 2
A addSourceBtn() 0 4 2
A setBrowseFolderImageURL() 0 3 1
A getStyle() 0 27 5
A __construct() 0 6 1
B onParentSet() 0 59 10
A buildToolbarDef() 0 15 1
A getToolbar() 0 3 1
A addCustomButton() 0 10 2
A buildSelectableColors() 0 16 5
A setContentsCss() 0 3 1
A setAllowedContent() 0 3 1
A addColorBtns() 0 4 2
A addParagraphBtns() 0 15 2
A setBodyID() 0 3 1
A addPlaceholderSelect() 0 4 3
A setToolbar() 0 3 1
A addCustomBtns() 0 4 2
A buildEditorOptions() 0 22 3
B addInsertBtns() 0 20 7
A fromXML() 0 10 1
A setBrowseFolderLinkURL() 0 3 1
A addStyleSelect() 0 4 2
A getBrowseFolder() 0 6 2
A addBasicStyleBtns() 0 13 2
A setBrowseFolderImageLinkURL() 0 3 1
A addLinkBtns() 0 6 2
A buildPlaceholderSelect() 0 5 3

How to fix   Complexity   

Complex Class

Complex classes like FormCKEdit often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use FormCKEdit, and based on these observations, apply Extract Interface, too.

1
<?php
2
declare(strict_types=1);
3
4
namespace SKien\Formgenerator;
5
6
/**
7
 * WYSIWYG - HTML input using CKEditor.
8
 * uses CKEditor Version 4.15
9
 *
10
 * For more information about download, install and integration of the CKEditor, see
11
 * CKEditorIntegration.md
12
 *
13
 * To enable filebrowsing on the server for the insert mage and insert link functionality
14
 * the RichFilemanager is used. For more information see
15
 * RichFilemanager.md
16
 *
17
 * @package Formgenerator
18
 * @author Stefanius <[email protected]>
19
 * @copyright MIT License - see the LICENSE file for details
20
 */
21
class FormCKEdit extends FormTextArea
22
{
23
    /** 'Source' - Button   */
24
    public const TB_SOURCE           = 0x00000002;
25
    /** Basic Styles:  Bold, Italic, Underline, Subscript, Superscript, RemoveFormat    */
26
    public const TB_BASIC_STYLES     = 0x00000004;
27
    /** Paragraph Formation: NumberedList, BulletedList, Outdent, Indent, JustifyLeft, -Center, -Right' */
28
    public const TB_PARAGRAPH        = 0x00000008;
29
    /** Links: link, Unlink */
30
    public const TB_LINKS            = 0x00000010;
31
    /** Insert Image    */
32
    public const TB_IMAGE            = 0x00000020;
33
    /** Colors: Text-, Backgroundcolor  */
34
    public const TB_COLOR            = 0x00000040;
35
    /** insert Table   */
36
    public const TB_TABLE            = 0x00000080;
37
    /** SelectBox for defined Styles    */
38
    public const TB_STYLES_SELECT    = 0x00000100;
39
    /** Select predefined Templates */
40
    public const TB_TEMPLATES        = 0x00000200;
41
    /** SelectBox for Placeholders  */
42
    public const TB_PLACEHOLDERS     = 0x00000400;
43
    /** Insert Codesnippet  */
44
    public const TB_SNIPPET          = 0x00000800;
45
    /** Insert Special Chars  */
46
    public const TB_SPECIAL_CHAR     = 0x00001000;
47
    /** Insert Iframe  */
48
    public const TB_IFRAME           = 0x00002000;
49
50
    /** small toolbar (only basic styles)   */
51
    public const TB_SMALL    = 0x00000004; // TB_BASIC_STYLES;
52
    /** insert objects   */
53
    public const TB_INSERT   = 0x000038A0; // TB_IMAGE | TB_TABLE | TB_SNIPPET | TB_SPECIAL_CHAR | TB_IFRAME
54
    /** toolbar for content edit (no colors, templates and objects)   */
55
    public const TB_CONTENT  = 0xfffff53d; // 0xffffffff & ~(TB_COLOR | TB_TEMPLATES | TB_INSERT | TB_SOURCE);
56
    /** full toolbar (no templates)   */
57
    public const TB_FULL     = 0xfffffdfd; // 0xffffffff & ~(TB_TEMPLATES | TB_SOURCE);
58
59
    /** custom button only with text   */
60
    public const BTN_TEXT           = 0x01;
61
    /** custom button only with icon   */
62
    public const BTN_ICON           = 0x02;
63
    /** custom button with text and icon  */
64
    public const BTN_TEXT_ICON      = 0x03;
65
66
    /** @var string the CSS file used inside the editarea    */
67
    protected string $strContentsCss = '';
68
    /** @var string the id of the editarea   */
69
    protected string $strBodyID;
70
    /** @var array<mixed> custom button definition ["func" => <buttonhandler>, "name" => <buttonname>]    */
71
    protected array $aCustomBtn = [];
72
    /** @var string allowed content    */
73
    protected string $strAllowedContent = '';
74
    /** @var int toolbar mask    */
75
    protected int $lToolbar;
76
    /** @var string initial folder to expand in filemanager for links   */
77
    protected string $strBrowseFolderLinkURL = '';
78
    /** @var string initial folder to expand in filemanager for images   */
79
    protected string $strBrowseFolderImageURL = '';
80
    /** @var string initial folder to expand in filemanager for image links   */
81
    protected string $strBrowseFolderImageLinkURL = '';
82
    /** @var boolean connect to this filemanger     */
83
    protected string $strConnectToFilemanager = '';
84
85
    /**
86
     * Creates a WYSIWYG editor.
87
     * @param string $strName
88
     * @param int $iRows
89
     * @param string $strWidth
90
     * @param int $wFlags
91
     */
92
    public function __construct(string $strName, int $iRows, string $strWidth = '100%', int $wFlags = 0)
93
    {
94
        // add 2 rows to increase height for toolbar
95
        parent::__construct($strName, 0, $iRows + 2, $strWidth, $wFlags);
96
        $this->strBodyID = 'editarea';
97
        $this->lToolbar = self::TB_CONTENT;
98
    }
99
100
    /**
101
     * {@inheritDoc}
102
     * @see \SKien\Formgenerator\FormElement::fromXML()
103
     */
104
    static public function fromXML(\DOMElement $oXMLElement, FormCollection $oFormParent) : ?FormElement
105
    {
106
        $strName = self::getAttribString($oXMLElement, 'name');
107
        $iRows = self::getAttribInt($oXMLElement, 'rows', 10);
108
        $strWidth = self::getAttribString($oXMLElement, 'width', '100%');
109
        $wFlags = self::getAttribFlags($oXMLElement);
110
        $oFormElement = new self($strName, $iRows, $strWidth, $wFlags);
111
        $oFormParent->add($oFormElement);
112
        $oFormElement->readAdditionalXML($oXMLElement);
113
        return $oFormElement;
114
    }
115
116
    /**
117
     * {@inheritDoc}
118
     * @see \SKien\Formgenerator\FormElement::readAdditionalXML()
119
     */
120
    public function readAdditionalXML(\DOMElement $oXMLElement) : void
121
    {
122
        parent::readAdditionalXML($oXMLElement);
123
        $this->setContentsCss(self::getAttribString($oXMLElement, 'content-css'));
124
        $this->setBodyID(self::getAttribString($oXMLElement, 'body-id'));
125
    }
126
127
    /**
128
     * Set the CSS file to use in the edit area.
129
     * @param string $strContentsCss
130
     */
131
    public function setContentsCss(string $strContentsCss) : void
132
    {
133
        $this->strContentsCss = $strContentsCss;
134
    }
135
136
    /**
137
     * Set the ID of the body.
138
     * This is the ID of the 'Container' element in which the text to be edited here
139
     * should be displayed. This ID is required so that the correct CSS selectors are
140
     * used for the display here in the editor.
141
     * @param string $strBodyID
142
     */
143
    public function setBodyID(string $strBodyID) : void
144
    {
145
        $this->strBodyID = $strBodyID;
146
    }
147
148
    /**
149
     * Add custom button to the beginning of the toolbar.
150
     * If icon specified take care it the path is absolute or relative to the script that
151
     * containing this CKEditor.
152
     * @param string $strName       Name (Text) of the Button
153
     * @param string $strFunction   JS-Function to handle click (func gets editor as paramter)
154
     * @param string $strIcon       Icon for the button
155
     * @param int $iType            Type of the button (FormCKEdit::BTN_TEXT, FormCKEdit::BTN_ICON or FormCKEdit::BTN_TXET_ICON)
156
     */
157
    public function addCustomButton(string $strName, string $strFunction, string $strIcon = '', int $iType = self::BTN_TEXT) : void
158
    {
159
        if (empty($strIcon)) {
160
            $iType = self::BTN_TEXT;
161
        }
162
        $this->aCustomBtn[] = [
163
            'func' => $strFunction,
164
            'name' => $strName,
165
            'icon' => $strIcon,
166
            'type' => $iType,
167
        ];
168
    }
169
170
    /**
171
     * Specify allowed content (see documentation of CKEdit for details)
172
     * @param string $strAllowedContent leave empty to allow everything (default)
173
     */
174
    public function setAllowedContent(string $strAllowedContent = '') : void
175
    {
176
        $this->strAllowedContent = $strAllowedContent;
177
    }
178
179
    /**
180
     * @param string $strBrowseFolderLinkURL
181
     */
182
    public function setBrowseFolderLinkURL(string $strBrowseFolderLinkURL) : void
183
    {
184
        $this->strBrowseFolderLinkURL = $strBrowseFolderLinkURL;
185
    }
186
187
    /**
188
     * @param string $strBrowseFolderImageURL
189
     */
190
    public function setBrowseFolderImageURL(string $strBrowseFolderImageURL) : void
191
    {
192
        $this->strBrowseFolderImageURL = $strBrowseFolderImageURL;
193
    }
194
195
    /**
196
     * @param string $strBrowseFolderImageLinkURL
197
     */
198
    public function setBrowseFolderImageLinkURL(string $strBrowseFolderImageLinkURL) : void
199
    {
200
        $this->strBrowseFolderImageLinkURL = $strBrowseFolderImageLinkURL;
201
    }
202
203
    /**
204
     * Load some configuratin after parent set.
205
     * {@inheritDoc}
206
     * @see \SKien\Formgenerator\FormElement::onParentSet()
207
     */
208
    protected function onParentSet() : void
209
    {
210
        $aCKEditor = [
211
            'Path' => $this->oFG->getConfig()->getString('CKEditor.Path'),
212
            'editorID' => $this->strName,
213
            'editorOptions' => $this->buildEditorOptions(),
214
            'customButtons' => $this->aCustomBtn,
215
        ];
216
        // pass the content through the JSON data
217
        if ($this->oFlags->isSet(FormFlags::SET_JSON_DATA)) {
218
            $aCKEditor['editorData'] = $this->oFG->getData()->getValue($this->strName);
219
        }
220
        $this->oFG->addConfigForJS('CKEditor', $aCKEditor);
221
222
        $strRfmPath = $this->oFG->getConfig()->getString('RichFilemanager.Path');
223
        if ($strRfmPath != '') {
224
            $this->strConnectToFilemanager = 'RichFilemanager';
0 ignored issues
show
Documentation Bug introduced by
The property $strConnectToFilemanager was declared of type boolean, but 'RichFilemanager' is of type string. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
225
            if (!file_exists($_SERVER['DOCUMENT_ROOT'] . $strRfmPath)) {
226
                if ($this->oFG->getDebugMode()) {
227
                    trigger_error('Can not find Rich Filemanager at [' . $_SERVER['DOCUMENT_ROOT'] . $strRfmPath . ']', E_USER_WARNING);
228
                }
229
            }
230
231
            $strBrowseFolderLinkURL = $this->getBrowseFolder($this->strBrowseFolderLinkURL, 'RichFilemanager.expandFolder.browseLinkURL');
232
            $strBrowseFolderImageURL = $this->getBrowseFolder($this->strBrowseFolderImageURL, 'RichFilemanager.expandFolder.browseImageURL');
233
            $strBrowseFolderImageLinkURL = $this->getBrowseFolder($this->strBrowseFolderImageLinkURL, 'RichFilemanager.expandFolder.browseImageLinkURL');
234
            $aRFM = [
235
                'Path' => $strRfmPath,
236
                'language' => $this->oFG->getConfig()->getString('RichFilemanager.language'),
237
                'expandFolder' => [
238
                    'browseLinkURL' => $strBrowseFolderLinkURL,
239
                    'browseImageURL' => $strBrowseFolderImageURL,
240
                    'browseImageLinkURL' => $strBrowseFolderImageLinkURL ?: $strBrowseFolderLinkURL
241
                ]
242
            ];
243
            $this->oFG->addConfigForJS('RichFilemanager', $aRFM);
244
        }
245
        $strElfPath = $this->oFG->getConfig()->getString('elFinder.Path');
246
        if ($strElfPath != '') {
247
            $this->strConnectToFilemanager = 'elFinder';
248
            if (!file_exists($_SERVER['DOCUMENT_ROOT'] . $strElfPath)) {
249
                if ($this->oFG->getDebugMode()) {
250
                    trigger_error('Can not find elFinder at [' . $_SERVER['DOCUMENT_ROOT'] . $strElfPath . ']', E_USER_WARNING);
251
                }
252
            }
253
254
            $strBrowseFolderLinkURL = $this->getBrowseFolder($this->strBrowseFolderLinkURL, 'elFinder.expandFolder.browseLinkURL');
255
            $strBrowseFolderImageURL = $this->getBrowseFolder($this->strBrowseFolderImageURL, 'elFinder.expandFolder.browseImageURL');
256
            $strBrowseFolderImageLinkURL = $this->getBrowseFolder($this->strBrowseFolderImageLinkURL, 'elFinder.expandFolder.browseImageLinkURL');
257
            $aELF = [
258
                'Path' => $strElfPath,
259
                'language' => $this->oFG->getConfig()->getString('elFinder.language'),
260
                'expandFolder' => [
261
                    'browseLinkURL' => $strBrowseFolderLinkURL,
262
                    'browseImageURL' => $strBrowseFolderImageURL,
263
                    'browseImageLinkURL' => $strBrowseFolderImageLinkURL ?: $strBrowseFolderLinkURL
264
                ]
265
            ];
266
            $this->oFG->addConfigForJS('elFinder', $aELF);
267
        }
268
    }
269
270
    /**
271
     * Gets the startfolder for different purposes.
272
     * Only read sttings from the config, if no folder has been set so far.
273
     * @param string $strFolder
274
     * @param string $strConfig
275
     * @return string
276
     */
277
    protected function getBrowseFolder(string $strFolder, string $strConfig) : string
278
    {
279
        if (strlen($strFolder) > 0) {
280
            return $strFolder;
281
        }
282
        return $this->oFG->getConfig()->getString($strConfig);
283
    }
284
285
    /**
286
     * Build CKEditor specific styles.
287
     * @return string
288
     */
289
    public function getStyle() : string
290
    {
291
        // If custom toolbar buttons defined, for each button dependent on the his
292
        // type (TEXT, ICON, TEXT+ICON) some styles have to be set.
293
        $strStyle = '';
294
        foreach ($this->aCustomBtn as $aBtn) {
295
            $strBtn = strtolower($aBtn['func']);
296
            $strDisplayLabel = (($aBtn['type'] & self::BTN_TEXT) != 0) ? 'inline' : 'none';
297
            $strDisplayIcon = (($aBtn['type'] & self::BTN_ICON) != 0) ? 'inline' : 'none';
298
            $strStyle .= '.cke_button__' . $strBtn . '_icon { display: ' . $strDisplayIcon . ' !important; }' . PHP_EOL;
299
            $strStyle .= '.cke_button__' . $strBtn . '_label { display: ' . $strDisplayLabel . ' !important; }' . PHP_EOL;
300
        }
301
302
        if (!empty($this->strConnectToFilemanager)) {
303
            $strStyle .= PHP_EOL .
304
                ".fm-modal {" . PHP_EOL .
305
                "    z-index: 10011; /** Because CKEditor image dialog was at 10010 */" . PHP_EOL .
306
                "    width:80%;" . PHP_EOL .
307
                "    height:80%;" . PHP_EOL .
308
                "    top: 10%;" . PHP_EOL .
309
                "    left:10%;" . PHP_EOL .
310
                "    border:0;" . PHP_EOL .
311
                "    position:fixed;" . PHP_EOL .
312
                "}";
313
        }
314
315
        return $strStyle;
316
    }
317
318
    /**
319
     * Define toolbar to display.
320
     * @param int $lToolbar
321
     */
322
    public function setToolbar(int $lToolbar) : void
323
    {
324
        $this->lToolbar = $lToolbar;
325
    }
326
327
    /**
328
     * Returns currently defined toolbar.
329
     * @return int
330
     */
331
    public function getToolbar() : int
332
    {
333
        return $this->lToolbar;
334
    }
335
336
    /**
337
     * Build the options to create the CKEditor instance.
338
     * @return array<mixed>
339
     */
340
    protected function buildEditorOptions() : array
341
    {
342
        if (strlen($this->strContentsCss) == 0) {
343
            trigger_error('No CSS Stylesheet set!', E_USER_WARNING);
344
        }
345
        $aCKEditor = [
346
            'contentsCss' => $this->strContentsCss,
347
            'skin' => $this->oFG->getConfig()->getString('CKEditor.skin', 'moonocolor'),
348
            'bodyId' => $this->strBodyID,
349
            'toolbar' => $this->buildToolbarDef(),
350
            'toolbarCanCollapse' => false,
351
            'uiColor' => $this->oFG->getConfig()->getString('CKEditor.uiColor', '#F8F8F8'),
352
            'pasteFilter' => $this->oFG->getConfig()->getString('CKEditor.pasteFilter', 'plain-text'),
353
            'colorButton_enableAutomatic' => $this->oFG->getConfig()->getBool('CKEditor.colorbutton.enableAutomatic', true),
354
            'colorButton_enableMore' => $this->oFG->getConfig()->getBool('CKEditor.colorbutton.enableMore', true),
355
            'allowedContent' => ($this->strAllowedContent ?: true),
356
            'resize_enabled' => false,
357
        ];
358
        $this->buildSelectableColors($aCKEditor);
359
        $this->buildPlaceholderSelect($aCKEditor);
360
361
        return $aCKEditor;
362
    }
363
364
    /**
365
     * Build config settings for the selectable colors.
366
     * @param array<mixed> $aCKEditor
367
     */
368
    protected function buildSelectableColors(array &$aCKEditor) : void
369
    {
370
        $aSelectableColorsRaw = $this->oFG->getConfig()->getArray('CKEditor.colorbutton.selectableColors');
371
        $aSelectableColors = [];
372
        foreach ($aSelectableColorsRaw as $color) {
373
            $aSelectableColors[] = ltrim($color, '#');
374
        }
375
        if (($this->lToolbar & self::TB_COLOR) != 0 && count($aSelectableColors) > 0) {
376
            $strColors = '';
377
            $strSep = '';
378
            foreach ($aSelectableColors as $strColor) {
379
                $strColors .= $strSep . $strColor;
380
                $strSep = ',';
381
            }
382
            $aCKEditor['colorButton_colors'] = $strColors;
383
            $aCKEditor['colorButton_colorsPerRow'] = $this->oFG->getConfig()->getInt('CKEditor.colorbutton.colorsPerRow', 6);
384
        }
385
    }
386
387
    /**
388
     * Build config for available placeholders in the placeholder-combobox.
389
     * @param array<mixed> $aCKEditor
390
     */
391
    protected function buildPlaceholderSelect(array &$aCKEditor) : void
392
    {
393
        $aPlaceholderselect = $this->oFG->getConfig()->getArray('CKEditor.placeholder');
394
        if (($this->lToolbar & self::TB_PLACEHOLDERS) != 0 && count($aPlaceholderselect) > 0) {
395
            $aCKEditor['placeholder_select'] = ['placeholders' => $aPlaceholderselect];
396
        }
397
    }
398
399
    /**
400
     * Returns currently defined toolbar as array for JSON-encoding.
401
     * @link https://ckeditor.com/latest/samples/toolbarconfigurator/index.html
402
     * @return array<mixed>
403
     */
404
    protected function buildToolbarDef() : array
405
    {
406
        $aToolbar = [];
407
        $this->addCustomBtns($aToolbar);
408
        $this->addBasicStyleBtns($aToolbar);
409
        $this->addParagraphBtns($aToolbar);
410
        $this->addLinkBtns($aToolbar);
411
        $this->addInsertBtns($aToolbar);
412
        $this->addColorBtns($aToolbar);
413
        $this->addStyleSelect($aToolbar);
414
        $this->addTemplateSelect($aToolbar);
415
        $this->addPlaceholderSelect($aToolbar);
416
        $this->addSourceBtn($aToolbar);
417
418
        return $aToolbar;
419
    }
420
421
    /**
422
     * Add all custom buttons at start of the toolbar.
423
     * @param array<mixed> $aToolbar reference to the toolbar array
424
     */
425
    protected function addCustomBtns(array &$aToolbar) : void
426
    {
427
        foreach ($this->aCustomBtn as $aBtn) {
428
            $aToolbar[] = ['items' => [$aBtn['func']]];
429
        }
430
    }
431
432
    /**
433
     * Add button group for basic styles.
434
     * @param array<mixed> $aToolbar reference to the toolbar array
435
     */
436
    protected function addBasicStyleBtns(array &$aToolbar) : void
437
    {
438
        if (($this->lToolbar & self::TB_BASIC_STYLES) != 0) {
439
            $aToolbar[] = [
440
                'name' => 'basicstyles',
441
                'items' => [
442
                    'Bold',
443
                    'Italic',
444
                    'Underline',
445
                    'Subscript',
446
                    'Superscript',
447
                    '-',
448
                    'RemoveFormat',
449
                ]
450
            ];
451
        }
452
    }
453
454
    /**
455
     * Add button group for paragraph formating.
456
     * @param array<mixed> $aToolbar reference to the toolbar array
457
     */
458
    protected function addParagraphBtns(array &$aToolbar) : void
459
    {
460
        if (($this->lToolbar & self::TB_PARAGRAPH) != 0) {
461
            $aToolbar[] = [
462
                'name' => 'paragraph',
463
                'items' => [
464
                    'NumberedList',
465
                    'BulletedList',
466
                    '-',
467
                    'Outdent',
468
                    'Indent',
469
                    '-',
470
                    'JustifyLeft',
471
                    'JustifyCenter',
472
                    'JustifyRight',
473
                ]
474
            ];
475
        }
476
    }
477
478
    /**
479
     * Add button group for links.
480
     * @param array<mixed> $aToolbar reference to the toolbar array
481
     */
482
    protected function addLinkBtns(array &$aToolbar) : void
483
    {
484
        if (($this->lToolbar & self::TB_LINKS) != 0) {
485
            $aToolbar[] = [
486
                'name' => 'links',
487
                'items' => ['Link', 'Unlink']
488
            ];
489
        }
490
    }
491
492
    /**
493
     * Add button group to insert objects.
494
     * - Images
495
     * - Snippets
496
     * - Tables
497
     * - Special Chars
498
     * - IFrames
499
     * @param array<mixed> $aToolbar reference to the toolbar array
500
     */
501
    protected function addInsertBtns(array &$aToolbar) : void
502
    {
503
        if (($this->lToolbar & self::TB_INSERT) != 0) {
504
            $aInsert = array();
505
            if (($this->lToolbar & self::TB_IMAGE) != 0) {
506
                $aInsert[] = 'Image';
507
            }
508
            if (($this->lToolbar & self::TB_SNIPPET) != 0) {
509
                $aInsert[] = 'CodeSnippet';
510
            }
511
            if (($this->lToolbar & self::TB_TABLE) != 0) {
512
                $aInsert[] = 'Table';
513
            }
514
            if (($this->lToolbar & self::TB_SPECIAL_CHAR) != 0) {
515
                $aInsert[] = 'SpecialChar';
516
            }
517
            if (($this->lToolbar & self::TB_IFRAME) != 0) {
518
                $aInsert[] = 'Iframe';
519
            }
520
            $aToolbar[] = ['name' => 'insert', 'items' => $aInsert];
521
        }
522
    }
523
524
    /**
525
     * Add button group for colors
526
     * @param array<mixed> $aToolbar reference to the toolbar array
527
     */
528
    protected function addColorBtns(array &$aToolbar) : void
529
    {
530
        if (($this->lToolbar & self::TB_COLOR) != 0) {
531
            $aToolbar[] = ['name' => 'color', 'items' => ['TextColor', 'BGColor']];
532
        }
533
    }
534
535
    /**
536
     * Add select list for styles
537
     * @param array<mixed> $aToolbar reference to the toolbar array
538
     */
539
    protected function addStyleSelect(array &$aToolbar) : void
540
    {
541
        if (($this->lToolbar & self::TB_STYLES_SELECT) != 0) {
542
            $aToolbar[] = ['items' => ['Styles']];
543
        }
544
    }
545
546
    /**
547
     * Add select list for templates
548
     * @param array<mixed> $aToolbar reference to the toolbar array
549
     */
550
    protected function addTemplateSelect(array &$aToolbar) : void
551
    {
552
        if (($this->lToolbar & self::TB_TEMPLATES) != 0) {
553
            $aToolbar[] = ['items' => ['Templates']];
554
        }
555
    }
556
557
    /**
558
     * Add select list for placeholders
559
     * @param array<mixed> $aToolbar reference to the toolbar array
560
     */
561
    protected function addPlaceholderSelect(array &$aToolbar) : void
562
    {
563
        if (($this->lToolbar & self::TB_PLACEHOLDERS) != 0 && count($this->oFG->getConfig()->getArray('CKEditor.placeholder')) > 0) {
564
            $aToolbar[] = ['items' => ['placeholder_select']];
565
        }
566
    }
567
568
    /**
569
     * Add button to switch in the source mode
570
     * @param array<mixed> $aToolbar reference to the toolbar array
571
     */
572
    protected function addSourceBtn(array &$aToolbar) : void
573
    {
574
        if (($this->lToolbar & self::TB_SOURCE) != 0) {
575
            $aToolbar[] = ['name' => 'document', 'items' => ['Source']];
576
        }
577
    }
578
}
579