Passed
Push — main ( dedf73...0dcdcf )
by Stefan
01:14
created

FormCKEdit::getToolbar()   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
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 3
rs 10
1
<?php
2
namespace SKien\Formgenerator;
3
4
/**
5
 * HTML input using CKEditor
6
 *
7
 * history:
8
 * date         version
9
 * 2020-05-12   initial version
10
 *
11
 * @package Formgenerator
12
 * @version 1.0.0
13
 * @author Stefanius <[email protected]>
14
 * @copyright MIT License - see the LICENSE file for details
15
 */
16
class FormCKEdit extends FormTextArea
17
{
18
    /** 'Source' - Button   */
19
    const   TB_SOURCE           = 0x00000002;
20
    /** Basic Styles:  Bold, Italic, Underline, Subscript, Superscript, RemoveFormat    */
21
    const   TB_BASIC_STYLES     = 0x00000004;
22
    /** Paragraph Formation: NumberedList, BulletedList, Outdent, Indent, JustifyLeft, -Center, -Right' */
23
    const   TB_PARAGRAPH        = 0x00000008;
24
    /** Links: link, Unlink */
25
    const   TB_LINKS            = 0x00000010;
26
    /** Insert Image    */
27
    const   TB_IMAGE            = 0x00000020;
28
    /** Colors: Text-, Backgroundcolor  */
29
    const   TB_COLOR            = 0x00000040;
30
    /** Table funtions insert and delete rows   */
31
    /* not working so far !!
32
     const  tbTable             = 0x00000080; */
33
    /** SelectBox for defined Styles    */
34
    const   TB_STYLES_SELECT    = 0x00000100;
35
    /** Select predefined Templates */
36
    const   TB_TEMPLATES        = 0x00000200;
37
    /** SelectBox for Placeholders  */
38
    const   TB_PLACEHOLDERS     = 0x00000400;
39
    /** Insert Codesnippet  */
40
    const   TB_SNIPPET          = 0x00000800;
41
    
42
    /** small toolbar (only basic styles)   */
43
    const   TB_SMALL    = 0x00000004; // self::TB_BASIC_STYLES;
44
    /** toolbar for content edit (no colors, templates and snippets)   */
45
    const   TB_CONTENT  = 0xfffff5bd; // 0xffffffff & ~( self::TB_COLOR | self::TB_TEMPLATES | self::TB_SNIPPET | TB_SOURCE);
46
    /** full toolbar (no templates)   */
47
    const   TB_FULL     = 0xfffffdfd; // 0xffffffff & ~(self::TB_TEMPLATES | TB_SOURCE);
48
    
49
    /** @var string the CSS file used inside the editarea    */
50
    protected string $strContentsCss;
51
    /** @var string the id of the editarea   */
52
    protected string $strBodyID;
53
    /** @var string the content for the editor as JSON   */
54
    protected ?string $strJsonData = null;
55
    /** @var array custom button definition ["func" => <buttonhandler>, "name" => <buttonname>]    */
56
    protected ?array $aCustomBtn = null;
57
    /** @var string allowed content    */
58
    protected ?string $strAllowedContent;
59
    /** @var int toolbar mask    */
60
    protected int $lToolbar;
61
    
62
    /**
63
     * Creates a WYSIWYG editor.
64
     * @param string $strName
65
     * @param string $strValue
66
     * @param int $iRows
67
     * @param string $strWidth
68
     * @param int $wFlags
69
     */
70
    public function __construct(string $strName, string $strValue, int $iRows, string $strWidth = '95%', int $wFlags = 0) 
71
    {
72
        if (($wFlags & FormInput::SET_JSON_DATA) != 0) {
73
            $this->strJsonData = $strValue;
74
            $strValue = '';
75
        }
76
        // add 2 rows to increase height for toolbar
77
        parent::__construct($strName, $strValue, 0, $iRows + 2, $strWidth, $wFlags);
78
        $this->bCreateScript = true;
79
        $this->bCreateStyle = true;
80
        $this->strContentsCss = '../style/ckeditarea.css';
81
        $this->strBodyID = 'editarea';
82
        $this->strAllowedContent = null;
83
        $this->lToolbar = self::TB_CONTENT;
84
    } 
85
86
    /**
87
     * Set the CSS file to use in the edit area.
88
     * @param string $strContentsCss
89
     */
90
    public function setContentsCss(string $strContentsCss) : void
91
    {
92
        $this->strContentsCss = $strContentsCss;
93
    }
94
95
    /**
96
     * Set the ID of the body.
97
     * This is the ID of the 'Container' element in which the text to be edited here 
98
     * should be displayed. This ID is required so that the correct CSS selectors are 
99
     * used for the display here in the editor. 
100
     * @param string $strBodyID
101
     */
102
    public function setBodyID(string $strBodyID) : void 
103
    {
104
        $this->strBodyID = $strBodyID;
105
    }
106
    
107
    /**
108
     * Add custom button to the beginning of the toolbar.
109
     * @param string $strName       Name (Text) of the Button
110
     * @param string $strFunction   JS-Function to handle click (func gets editor as paramter)
111
     */
112
    public function addCustomButton(string $strName, string $strFunction) : void 
113
    {
114
        if (!is_array($this->aCustomBtn)) {
115
            $this->aCustomBtn = array();
116
        }
117
        
118
        $this->aCustomBtn[] = array('func' => $strFunction, 'name' => $strName);
119
    }
120
    
121
    /**
122
     * Specify allowed content (see documentation of CKEdit for details)
123
     * @param string $strAllowedContent leave empty to allow everything (default)  
124
     */
125
    public function setAllowedContent(string $strAllowedContent = '') : void
126
    {
127
        $this->strAllowedContent = $strAllowedContent;
128
    }
129
    
130
    /**
131
     * Build the JS script to Load the editor:
132
     * - contentCSS
133
     * - bodyID
134
     * - Toolbar
135
     * - Custom Buttons
136
     */
137
    public function getScript() : string 
138
    {
139
        $aToolbar = array();;
140
        if (is_array($this->aCustomBtn) && count($this->aCustomBtn) > 0) {
141
            reset($this->aCustomBtn);
142
            foreach ($this->aCustomBtn as $aBtn) {
143
                $aToolbar[] = array('items' => array($aBtn['func']));
144
            }
145
        }
146
        $aToolbar = array_merge($aToolbar, $this->getToolbarDef());
147
        
148
        // just everything allowed ...
149
        $strAllowedContent = "true";
150
        if (strlen($this->strAllowedContent) > 0) {
151
            $strAllowedContent = "'" . $this->strAllowedContent . "'";
152
        }
153
        
154
        $strScript  = 
155
            "var editor = null;" . PHP_EOL .
156
            "function LoadEditor()" . PHP_EOL .
157
            "{" . PHP_EOL .
158
            "    // get initial size of textarea to replace" . PHP_EOL .
159
            "    var oTA = document.getElementById('" . $this->strName . "');" . PHP_EOL .
160
            "    var iHeight = 80;" . PHP_EOL .
161
            "    if (oTA) {" . PHP_EOL .
162
            "        iHeight = oTA.offsetHeight;" . PHP_EOL .
163
            "        iWidth = oTA.offsetWidth;" . PHP_EOL .
164
            "    }" . PHP_EOL .
165
            "    // create and Initialize HTML-Editor" . PHP_EOL .
166
            "    editor = CKEDITOR.replace('" . $this->strName . "' , {" . PHP_EOL .
167
            "            contentsCss : '" . $this->strContentsCss . "'," . PHP_EOL .
168
            "            bodyId : '" . $this->strBodyID . "'," . PHP_EOL .
169
            "            removePlugins : 'elementspath'," . PHP_EOL .
170
            "            toolbar: " . json_encode($aToolbar) . ", " .
171
            "            toolbarCanCollapse : false," . PHP_EOL .
172
            "            pasteFilter : 'plain-text'," . PHP_EOL .
173
            "            allowedContent : " . $strAllowedContent . "," . PHP_EOL .
174
            "            resize_enabled : false" . PHP_EOL .
175
            "        });" . PHP_EOL;
176
        
177
        // commands for custom buttons
178
        if (is_array($this->aCustomBtn) && count($this->aCustomBtn) > 0) {
179
            reset($this->aCustomBtn);
180
            foreach ($this->aCustomBtn as $aBtn) {
181
                $strButton = $aBtn['func'];
182
                $strCommand = 'cmd_' . $strButton;
183
                $strName = $aBtn['name'];
184
                $strScript .= "    editor.addCommand('" . $strCommand . "', { exec: function(editor) { " . $strButton . "(editor);  } });" . PHP_EOL;
185
                $strScript .= "    editor.ui.addButton('" . $strButton . "', { label: '" . $strName . "', command: '" . $strCommand . "' });" . PHP_EOL;
186
            }
187
        }
188
        // resize to desired size
189
        $strScript .= PHP_EOL;
190
        $strScript .= "    CKEDITOR.on('instanceReady', function(event) {" . PHP_EOL;
191
        $strScript .= "            editor.resize(iWidth, iHeight);" . PHP_EOL;
192
        $strScript .= "        });" . PHP_EOL;
193
        
194
        // if data to edit provided in JSON format, set it
195
        if (($this->wFlags & self::SET_JSON_DATA) != 0 && $this->strJsonData != '') {
196
            $strScript .= PHP_EOL;
197
            $strScript .= '    editor.setData(' . json_encode($this->strJsonData, JSON_PRETTY_PRINT) . ');' . PHP_EOL;
198
        }       
199
        $strScript .= "}" . PHP_EOL;
200
        
201
        return $strScript;
202
    }
203
    
204
    /**
205
     * {@inheritDoc}
206
     * @see \SKien\Formgenerator\FormElement::getStyle()
207
     */
208
    public function getStyle() : string 
209
    {
210
        $strStyle  = '';
211
        
212
        if (is_array($this->aCustomBtn) && count($this->aCustomBtn) > 0) {
213
            reset($this->aCustomBtn);
214
            foreach ($this->aCustomBtn as $aBtn) {
215
                $strBtn = strtolower($aBtn['func']);
216
                $strStyle .= '.cke_button__' . $strBtn . '_icon { display: none !important; }' . PHP_EOL;
217
                $strStyle .= '.cke_button__' . $strBtn . '_label { display: inline !important; }' . PHP_EOL;
218
            }
219
        }
220
        
221
        return $strStyle;
222
    }
223
    
224
    /**
225
     * Define toolbar to display.
226
     * @param int $lToolbar
227
     */
228
    public function setToolbar(int $lToolbar) : void
229
    {
230
        $this->lToolbar = $lToolbar;
231
    }
232
    
233
    /**
234
     * Returns currently defined toolbar.
235
     * @return int
236
     */
237
    public function getToolbar() : int
238
    {
239
        return $this->lToolbar;
240
    }
241
    
242
    /**
243
     * Returns currently defined toolbar as array for JSON-encoding.
244
     * @return array
245
     */
246
    public function getToolbarDef() : array
247
    {
248
        $aToolbar = array();
249
        $this->addBasicStyleBtns($aToolbar);
250
        $this->addParagraphBtns($aToolbar);
251
        $this->addLinkBtns($aToolbar);
252
        $this->addImageSnippetBtns($aToolbar);
253
        $this->addColorBtns($aToolbar);
254
        $this->addStyleSelect($aToolbar);
255
        $this->addTemplateSelect($aToolbar);
256
        $this->addPlaceholderSelect($aToolbar);
257
        $this->addSourceBtn($aToolbar);
258
        
259
        return $aToolbar;
260
    }
261
    
262
    /**
263
     * Add button group for basic styles. 
264
     * @param array $aToolbar reference to the toolbar array
265
     */
266
    protected function addBasicStyleBtns(array &$aToolbar) : void
267
    {
268
        if (($this->lToolbar & self::TB_BASIC_STYLES) != 0)
269
            $aToolbar[] = array('name' => 'basicstyles',   'items' => array('Bold','Italic','Underline','Subscript','Superscript','-','RemoveFormat'));
270
    }
271
    
272
    /**
273
     * Add button group for paragraph formating. 
274
     * @param array $aToolbar reference to the toolbar array
275
     */
276
    protected function addParagraphBtns(array &$aToolbar) : void
277
    {
278
        if (($this->lToolbar & self::TB_PARAGRAPH) != 0)
279
            $aToolbar[] = array('name' => 'paragraph',     'items' => array('NumberedList','BulletedList','-','Outdent', 'Indent','-','JustifyLeft','JustifyCenter','JustifyRight'));
280
    }
281
    
282
    /**
283
     * Add button group for links. 
284
     * @param array $aToolbar reference to the toolbar array
285
     */
286
    protected function addLinkBtns(array &$aToolbar) : void
287
    {
288
        if (($this->lToolbar & self::TB_LINKS) != 0)
289
            $aToolbar[] = array('name' => 'links',         'items' => array('Link','Unlink'));
290
    }
291
    
292
    /**
293
     * Add button group for images and snippets 
294
     * @param array $aToolbar reference to the toolbar array
295
     */
296
    protected function addImageSnippetBtns(array &$aToolbar) : void
297
    {
298
        if (($this->lToolbar & (self::TB_IMAGE | self::TB_SNIPPET)) != 0) {
299
            $aInsert = array();
300
            if (($this->lToolbar & self::TB_IMAGE) != 0)
301
                $aInsert[] = 'Image';
302
            if (($this->lToolbar & self::TB_SNIPPET) != 0)
303
                $aInsert[] = 'CodeSnippet';
304
            $aToolbar[] = array('name' => 'insert',        'items' => $aInsert);
305
        }
306
    }
307
    
308
    /**
309
     * Add button group for colors 
310
     * @param array $aToolbar reference to the toolbar array
311
     */
312
    protected function addColorBtns(array &$aToolbar) : void
313
    {
314
        if (($this->lToolbar & self::TB_COLOR) != 0)
315
            $aToolbar[] = array('name' => 'color',         'items' => array('TextColor','BGColor'));
316
    }
317
    
318
    /**
319
     * Add select list for styles 
320
     * @param array $aToolbar reference to the toolbar array
321
     */
322
    protected function addStyleSelect(array &$aToolbar) : void
323
    {
324
        if (($this->lToolbar & self::TB_STYLES_SELECT) != 0)
325
            $aToolbar[] = array('items' => array('Styles'));
326
    }
327
    
328
    /**
329
     * Add select list for templates 
330
     * @param array $aToolbar reference to the toolbar array
331
     */
332
    protected function addTemplateSelect(array &$aToolbar) : void
333
    {
334
        if (($this->lToolbar & self::TB_TEMPLATES) != 0)
335
            $aToolbar[] = array('items' => array('Templates'));
336
    }
337
    
338
    /**
339
     * Add select list for placeholders 
340
     * @param array $aToolbar reference to the toolbar array
341
     */
342
    protected function addPlaceholderSelect(array &$aToolbar) : void
343
    {
344
        if (($this->lToolbar & self::TB_PLACEHOLDERS) != 0)
345
            $aToolbar[] = array('items' => array('placeholder_select'));
346
    }
347
    
348
    /**
349
     * Add button to switch in the source mode 
350
     * @param array $aToolbar reference to the toolbar array
351
     */
352
    protected function addSourceBtn(array &$aToolbar) : void
353
    {
354
        if (($this->lToolbar & self::TB_SOURCE) != 0)
355
            $aToolbar[] = array('name' => 'document',      'items' => array('Source'));
356
    
357
    }
358
}
359