Passed
Branch php-cs-fixer (b9836a)
by Fabio
15:02
created

THtmlArea4   B

Complexity

Total Complexity 39

Size/Duplication

Total Lines 375
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 375
rs 8.2857
c 0
b 0
f 0
wmc 39

22 Methods

Rating   Name   Duplication   Size   Complexity  
A setCulture() 0 3 1
B parseEditorOptions() 0 19 5
B getLanguageSuffix() 0 16 6
A setEnableVisualEdit() 0 3 1
A getEnableVisualEdit() 0 3 1
A getEditorOptions() 0 23 2
B copyCustomPlugins() 0 11 5
A loadJavascriptLibrary() 0 5 1
A getAutoPostBack() 0 3 2
A getAvailableThemes() 0 3 1
A getCustomPluginPath() 0 3 1
A getAvailablePlugins() 0 3 1
A registerEditorClientScript() 0 11 1
A __construct() 0 4 1
A getClientClassName() 0 3 1
A setTextMode() 0 3 1
A addAttributesToRender() 0 9 3
A setCustomPluginPath() 0 3 1
A getTextMode() 0 3 1
A getCulture() 0 3 1
A getOptions() 0 3 1
A setOptions() 0 3 1
1
<?php
2
/**
3
 * THtmlArea4 class file.
4
 *
5
 * @author Fabio Bas <ctrlaltca[at]gmail[dot]com>
6
 * @link https://github.com/pradosoft/prado
7
 * @copyright Copyright &copy; 2005-2016 The PRADO Group
8
 * @license https://github.com/pradosoft/prado/blob/master/LICENSE
9
 * @package Prado\Web\UI\WebControls
10
 */
11
12
namespace Prado\Web\UI\WebControls;
13
14
use Prado\Exceptions\TInvalidOperationException;
15
use Prado\Prado;
16
use Prado\TApplicationMode;
17
use Prado\TPropertyValue;
18
use Prado\Web\Javascripts\TJavaScript;
19
20
/**
21
 * THtmlArea4 class
22
 *
23
 * THtmlArea4 wraps the visual editing functionalities provided by the
24
 * version 4 of TinyMCE project {@link http://tinymce.com/}. It has been
25
 * developed as a plug'n'play substitute for {@link THtmlArea}, that is
26
 * based on the previous iteration (version 3) of the same project.
27
 * Please note that both components can't be used together in the same page.
28
 *
29
 * THtmlArea displays a WYSIWYG text area on the Web page for user input
30
 * in the HTML format. The text displayed in the THtmlArea component is
31
 * specified or determined by using the <b>Text</b> property.
32
 *
33
 * To enable the visual editting on the client side, set the property
34
 * <b>EnableVisualEdit</b> to true (which is default value).
35
 * To set the size of the editor when the visual editting is enabled,
36
 * set the <b>Width</b> and <b>Height</b> properties instead of
37
 * <b>Columns</b> and <b>Rows</b> because the latter has no meaning
38
 * under the situation.
39
 *
40
 * The default editor gives only the basic tool bar. To change or add
41
 * additional tool bars, use the {@link setOptions Options} property to add additional
42
 * editor options with each options on a new line.
43
 * See http://www.tinymce.com/wiki.php/Configuration
44
 * for a list of options. The options can be change/added as shown in the
45
 * following example.
46
 * <code>
47
 * <com:THtmlArea>
48
 *       <prop:Options>
49
 *         language : "de"
50
 *         plugins: [ advlist anchor autolink autoresize autosave bbcode charmap code contextmenu directionality emoticons fullpage fullscreen hr image importcss insertdatetime layer legacyoutput link lists media nonbreaking noneditable pagebreak paste preview print save searchreplace spellchecker tabfocus table template textcolor visualblocks visualchars wordcount ]
51
 *         toolbar: "undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image     | print preview media",
52
 *         statusbar: false
53
 *      </prop:Options>
54
 * </com:THtmlArea>
55
 * </code>
56
 *
57
 * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
58
 * @package Prado\Web\UI\WebControls
59
 * @since 3.0
60
 */
61
class THtmlArea4 extends TTextBox
62
{
63
	/**
64
	 * @var array list of locale => language file pairs.
65
	 */
66
	private static $_langs = [
67
			'ar' => 'ar',
68
			'bg_BG' => 'bg_BG',
69
			'bs' => 'bs',
70
			'ca' => 'ca',
71
			'cs' => 'cs',
72
			'cy' => 'cy',
73
			'da' => 'da',
74
			'de' => 'de',
75
			'de_AT' => 'de_AT',
76
			'el' => 'el',
77
			'es' => 'es',
78
			'et' => 'et',
79
			'eu' => 'eu',
80
			'fa' => 'fa',
81
			'fi' => 'fi',
82
			'fo' => 'fo',
83
			'fr_FR' => 'fr_FR',
84
			'gl' => 'gl',
85
			'he_IL' => 'he_IL',
86
			'hr' => 'hr',
87
			'hu_HU' => 'hu_HU',
88
			'id' => 'id',
89
			'it' => 'it',
90
			'ja' => 'ja',
91
			'ka_GE' => 'ka_GE',
92
			'ko_KR' => 'ko_KR',
93
			'lb' => 'lb',
94
			'lt' => 'lt',
95
			'lv' => 'lv',
96
			'nb_NO' => 'nb_NO',
97
			'nl' => 'nl',
98
			'pl' => 'pl',
99
			'pt_BR' => 'pt_BR',
100
			'pt_PT' => 'pt_PT',
101
			'ro' => 'ro',
102
			'ru' => 'ru',
103
			'si_LK' => 'si_LK',
104
			'sk' => 'sk',
105
			'sl_SI' => 'sl_SI',
106
			'sr' => 'sr',
107
			'sv_SE' => 'sv_SE',
108
			'ta' => 'ta',
109
			'ta_IN' => 'ta_IN',
110
			'th_TH' => 'th_TH',
111
			'tr_TR' => 'tr_TR',
112
			'ug' => 'ug',
113
			'uk' => 'uk',
114
			'uk_UA' => 'uk_UA',
115
			'vi' => 'vi',
116
			'vi_VN' => 'vi_VN',
117
			'zh_CN' => 'zh_CN',
118
			'zh_TW' => 'zh_TW',
119
		];
120
121
	/**
122
	 * @var array list of default plugins to load, override using getAvailablePlugins();
123
	 */
124
	private static $_plugins = [
125
		'advlist',
126
		'anchor',
127
		'autolink',
128
		'autoresize',
129
		'autosave',
130
		'bbcode',
131
		'charmap',
132
		'code',
133
		'contextmenu',
134
		'directionality',
135
		'emoticons',
136
		'fullpage',
137
		'fullscreen',
138
		'hr',
139
		'image',
140
		'importcss',
141
		'insertdatetime',
142
		'layer',
143
		'legacyoutput',
144
		'link',
145
		'lists',
146
		'media',
147
		'nonbreaking',
148
		'noneditable',
149
		'pagebreak',
150
		'paste',
151
		'preview',
152
		'print',
153
		'save',
154
		'searchreplace',
155
		'spellchecker',
156
		'tabfocus',
157
		'table',
158
		'template',
159
		'textcolor',
160
		'visualblocks',
161
		'visualchars',
162
		'wordcount',
163
	];
164
165
	/**
166
	 * @var array default themes to load
167
	 */
168
	private static $_themes = [
169
		'modern',
170
	];
171
172
	/**
173
	 * Constructor.
174
	 * Sets default width and height.
175
	 */
176
	public function __construct()
177
	{
178
		$this->setWidth('600px');
179
		$this->setHeight('250px');
180
	}
181
182
	/**
183
	 * Overrides the parent implementation.
184
	 * TextMode for THtmlArea control is always 'MultiLine'
185
	 * @return string the behavior mode of the THtmlArea component.
186
	 */
187
	public function getTextMode()
188
	{
189
		return 'MultiLine';
190
	}
191
192
	/**
193
	 * Overrides the parent implementation.
194
	 * TextMode for THtmlArea is always 'MultiLine' and cannot be changed to others.
195
	 * @param string the text mode
196
	 */
197
	public function setTextMode($value)
198
	{
199
		throw new TInvalidOperationException("htmlarea_textmode_readonly");
200
	}
201
202
	/**
203
	 * @return boolean whether change of the content should cause postback. Return false if EnableVisualEdit is true.
204
	 */
205
	public function getAutoPostBack()
206
	{
207
		return $this->getEnableVisualEdit() ? false : parent::getAutoPostBack();
208
	}
209
210
	/**
211
	 * @return boolean whether to show WYSIWYG text editor. Defaults to true.
212
	 */
213
	public function getEnableVisualEdit()
214
	{
215
		return $this->getViewState('EnableVisualEdit', true);
216
	}
217
218
	/**
219
	 * Sets whether to show WYSIWYG text editor.
0 ignored issues
show
Bug introduced by
The type Prado\Web\UI\WebControls\whether was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
220
	 * @param boolean whether to show WYSIWYG text editor
221
	 */
222
	public function setEnableVisualEdit($value)
223
	{
224
		$this->setViewState('EnableVisualEdit', TPropertyValue::ensureBoolean($value), true);
225
	}
226
227
	/**
228
	 * Gets the current culture.
229
	 * @return string current culture, e.g. de_AT.
230
	 */
231
	public function getCulture()
232
	{
233
		return $this->getViewState('Culture', '');
234
	}
235
236
	/**
237
	 * Sets the culture/language for the html area
0 ignored issues
show
Bug introduced by
The type Prado\Web\UI\WebControls\a was not found. Did you mean a? If so, make sure to prefix the type with \.
Loading history...
238
	 * @param string a culture string, e.g. de_AT.
239
	 */
240
	public function setCulture($value)
241
	{
242
		$this->setViewState('Culture', $value, '');
243
	}
244
245
	/**
246
	 * Gets the list of options for the WYSIWYG (TinyMCE) editor
247
	 * @see http://www.tinymce.com/wiki.php/Configuration
248
	 * @return string options
249
	 */
250
	public function getOptions()
251
	{
252
		return $this->getViewState('Options', '');
253
	}
254
255
	/**
256
	 * Sets the list of options for the WYSIWYG (TinyMCE) editor
0 ignored issues
show
Bug introduced by
The type Prado\Web\UI\WebControls\options was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
257
	 * @see http://www.tinymce.com/wiki.php/Configuration
258
	 * @param string options
259
	 */
260
	public function setOptions($value)
261
	{
262
		$this->setViewState('Options', $value, '');
263
	}
264
265
	/**
266
	 * @param string path to custom plugins to be copied.
0 ignored issues
show
Bug introduced by
The type Prado\Web\UI\WebControls\path was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
267
	 */
268
	public function setCustomPluginPath($value)
269
	{
270
		$this->setViewState('CustomPluginPath', $value);
271
	}
272
273
	/**
274
	 * @return string path to custom plugins to be copied.
275
	 */
276
	public function getCustomPluginPath()
277
	{
278
		return $this->getViewState('CustomPluginPath');
279
	}
280
281
	/**
282
	 * Adds attribute name-value pairs to renderer.
283
	 * This method overrides the parent implementation by registering
284
	 * additional javacript code.
285
	 * @param THtmlWriter the writer used for the rendering purpose
286
	 */
287
	protected function addAttributesToRender($writer)
288
	{
289
		if($this->getEnableVisualEdit() && $this->getEnabled(true))
290
		{
291
			$writer->addAttribute('id', $this->getClientID());
292
			$this->registerEditorClientScript($writer);
293
		}
294
295
		parent::addAttributesToRender($writer);
296
	}
297
298
	/**
299
	 * Returns a list of plugins to be loaded.
300
	 * Override this method to customize.
301
	 * @return array list of plugins to be loaded
302
	 */
303
	public function getAvailablePlugins()
304
	{
305
		return self::$_plugins;
306
	}
307
308
	/**
309
	 * @return array list of available themese
310
	 */
311
	public function getAvailableThemes()
312
	{
313
		return self::$_themes;
314
	}
315
316
	protected function loadJavascriptLibrary()
317
	{
318
		$scripts = $this->getPage()->getClientScript();
319
		$scripts->registerPradoScript('htmlarea4');
320
		$this->copyCustomPlugins();
321
	}
322
323
	/**
324
	 * Registers the editor javascript file and code to initialize the editor.
325
	 */
326
	protected function registerEditorClientScript($writer)
0 ignored issues
show
Unused Code introduced by
The parameter $writer is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

326
	protected function registerEditorClientScript(/** @scrutinizer ignore-unused */ $writer)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
327
	{
328
		$this->loadJavascriptLibrary();
329
		$scripts = $this->getPage()->getClientScript();
330
		$options = [
331
			'EditorOptions' => $this->getEditorOptions()
332
		];
333
334
		$options = TJavaScript::encode($options, true, true);
335
		$script = "new {$this->getClientClassName()}($options)";
336
		$scripts->registerEndScript('prado:THtmlArea4' . $this->ClientID, $script);
0 ignored issues
show
Bug Best Practice introduced by
The property ClientID does not exist on Prado\Web\UI\WebControls\THtmlArea4. Since you implemented __get, consider adding a @property annotation.
Loading history...
337
	}
338
339
	protected function copyCustomPlugins()
340
	{
341
		if($plugins = $this->getCustomPluginPath())
342
		{
343
			$basepath = $this->getPage()->getClientScript()->getPradoScriptAssetPath('tinymce');
344
			$assets = $this->getApplication()->getAssetManager();
345
			$path = is_dir($plugins) ? $plugins : Prado::getPathOfNameSpace($plugins);
346
			$name = basename($path);
347
			$dest = $basepath . '/plugins/' . $name;
348
			if(!is_dir($dest) || $this->getApplication()->getMode() !== TApplicationMode::Performance)
0 ignored issues
show
introduced by
The condition ! is_dir($dest) || $this...cationMode::Performance can never be false.
Loading history...
349
				$assets->copyDirectory($path, $dest);
350
		}
351
	}
352
353
	/**
354
	 * Default editor options gives basic tool bar only.
355
	 * @return array editor initialization options.
356
	 */
357
	protected function getEditorOptions()
358
	{
359
		$options['mode'] = 'exact';
0 ignored issues
show
Comprehensibility Best Practice introduced by
$options was never initialized. Although not strictly required by PHP, it is generally a good practice to add $options = array(); before regardless.
Loading history...
360
		$options['elements'] = $this->getClientID();
361
		$options['language'] = $this->getLanguageSuffix($this->getCulture());
362
		//$options['theme'] = 'modern'; //default
363
		// mimic previous (tinyMCE3) sizing behaviour
364
		$options['width'] = $this->getWidth();
365
		$options['height'] = $this->getHeight();
366
		$options['resize'] = 'both';
367
		$options['menubar'] = false;
368
		if($this->getReadOnly())
369
		{
370
			$options['readonly'] = true;
371
			$options['toolbar'] = false;
372
			$options['menubar'] = false;
373
			$options['statusbar'] = false;
374
		}
375
376
		$options['extended_valid_elements'] = 'a[name|href|target|title|onclick],img[class|src|border=0|alt|title|hspace|vspace|width|height|align|onmouseover|onmouseout|name],hr[class|width|size|noshade],font[face|size|color|style],span[class|align|style]';
377
378
		$options = array_merge($options, $this->parseEditorOptions($this->getOptions()));
379
		return $options;
380
	}
381
382
	/**
383
	 * Parse additional options set in the Options property.
384
	 * @return array additional custom options
385
	 */
386
	protected function parseEditorOptions($string)
387
	{
388
		$options = [];
389
		$substrings = preg_split('/,\s*\n|\n/', trim($string));
390
		foreach($substrings as $bits)
391
		{
392
			$option = explode(":", $bits, 2);
393
394
			if(count($option) == 2)
395
			{
396
				$value = trim(trim($option[1]), "'\"");
397
				if (($s = strtolower($value)) === 'false')
398
					$value = false;
399
				elseif ($s === 'true')
400
					$value = true;
401
				$options[trim($option[0])] = $value;
402
			}
403
		}
404
		return $options;
405
	}
406
407
	/**
408
	 * @return string localized editor interface language extension.
409
	 */
410
	protected function getLanguageSuffix($culture)
411
	{
412
		$app = $this->getApplication()->getGlobalization();
413
		if(empty($culture) && ($app !== null))
414
			$culture = $app->getCulture();
415
		$variants = [];
416
		if($app !== null)
417
			$variants = $app->getCultureVariants($culture);
418
419
		foreach($variants as $variant)
420
		{
421
			if(isset(self::$_langs[$variant]))
422
				return self::$_langs[$variant];
423
		}
424
425
		return 'en';
426
	}
427
428
	/**
429
	 * Gets the name of the javascript class responsible for performing postback for this control.
430
	 * This method overrides the parent implementation.
431
	 * @return string the javascript class name
432
	 */
433
	protected function getClientClassName()
434
	{
435
		return 'Prado.WebUI.THtmlArea4';
436
	}
437
}
438