ILIAS  release_8 Revision v8.24
class.ilTextAreaInputGUI.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
27{
28 protected array $rteSupport = [];
29 protected string $value = "";
30 protected int $cols = 30;
31 protected int $rows = 5;
32 protected bool $usert = false;
33 protected array $rtetags = [];
34 protected array $plugins = [];
35 protected array $removeplugins = [];
36 protected array $buttons = [];
37 protected array $rtesupport = [];
38 protected bool $use_tags_for_rte_only = true;
39 protected int $max_num_chars = 0;
40 protected int $min_num_chars = 0;
41 protected int $initial_rte_width = 795;
42 protected array $disabled_buttons = array();
43 protected bool $usePurifier = false;
45 protected ?string $root_block_element = null;
46
47 protected array $rte_tag_set = array(
48 "mini" => array("strong", "em", "u", "ol", "li", "ul", "blockquote", "a", "p", "span", "br"), // #13286/#17981
49 "standard" => array("strong", "em", "u", "ol", "li", "ul", "p", "div",
50 "i", "b", "code", "sup", "sub", "pre", "strike", "gap"),
51 "extended" => array(
52 "a","blockquote","br","cite","code","div","em","h1","h2","h3",
53 "h4","h5","h6","hr","li","ol","p",
54 "pre","span","strike","strong","sub","sup","u","ul",
55 "i", "b", "gap"),
56 "extended_img" => array(
57 "a","blockquote","br","cite","code","div","em","h1","h2","h3",
58 "h4","h5","h6","hr","img","li","ol","p",
59 "pre","span","strike","strong","sub","sup","u","ul",
60 "i", "b", "gap"),
61 "extended_table" => array(
62 "a","blockquote","br","cite","code","div","em","h1","h2","h3",
63 "h4","h5","h6","hr","li","ol","p",
64 "pre","span","strike","strong","sub","sup","table","td",
65 "tr","u","ul", "i", "b", "gap"),
66 "extended_table_img" => array(
67 "a","blockquote","br","cite","code","div","em","h1","h2","h3",
68 "h4","h5","h6","hr","img","li","ol","p",
69 "pre","span","strike","strong","sub","sup","table","td",
70 "tr","u","ul", "i", "b", "gap"),
71 "full" => array(
72 "a","blockquote","br","cite","code","div","em","h1","h2","h3",
73 "h4","h5","h6","hr","img","li","ol","p",
74 "pre","span","strike","strong","sub","sup","table","td",
75 "tr","u","ul","ruby","rbc","rtc","rb","rt","rp", "i", "b", "gap"));
76
77 public function __construct(
78 string $a_title = "",
79 string $a_postvar = ""
80 ) {
81 global $DIC;
82
83 $this->lng = $DIC->language();
84 parent::__construct($a_title, $a_postvar);
85 $this->setType("textarea");
86 $this->setRteTagSet("standard");
87 $this->plugins = array();
88 $this->removeplugins = array();
89 $this->buttons = array();
90 $this->rteSupport = array();
91 }
92
93 public function setValue(string $a_value): void
94 {
95 $this->value = $a_value;
96 }
97
98 public function getValue(): string
99 {
100 return $this->value;
101 }
102
106 public function setCols(int $a_cols): void
107 {
108 // obsolete because of bootstrap
109 $this->cols = $a_cols;
110 }
111
112 public function getCols(): int
113 {
114 return $this->cols;
115 }
116
117 public function setRows(int $a_rows): void
118 {
119 $this->rows = $a_rows;
120 }
121
122 public function getRows(): int
123 {
124 return $this->rows;
125 }
126
127 // Set Maximum number of characters allowed.
128 public function setMaxNumOfChars(int $a_number): void
129 {
130 $this->max_num_chars = $a_number;
131 }
132
133 public function getMaxNumOfChars(): int
134 {
136 }
137
138 public function setMinNumOfChars(int $a_number): void
139 {
140 $this->min_num_chars = $a_number;
141 }
142
143 public function getMinNumOfChars(): int
144 {
146 }
147
148 public function setUseRte(bool $a_usert, string $version = ''): void
149 {
150 $this->usert = $a_usert;
151 $this->rteSupport['version'] = $version;
152 }
153
154 public function getUseRte(): bool
155 {
156 return $this->usert;
157 }
158
159 public function addPlugin(string $a_plugin): void
160 {
161 $this->plugins[$a_plugin] = $a_plugin;
162 }
163
164 public function removePlugin(string $a_plugin): void
165 {
166 $this->removeplugins[$a_plugin] = $a_plugin;
167 }
168
169 // Add RTE button.
170 public function addButton(string $a_button): void
171 {
172 $this->buttons[$a_button] = $a_button;
173 }
174
175 public function removeButton(string $a_button): void
176 {
177 unset($this->buttons[$a_button]);
178 }
179
183 public function setRTESupport(
184 int $obj_id,
185 string $obj_type,
186 string $module,
187 ?string $cfg_template = null,
188 bool $hide_switch = false,
189 ?string $version = null
190 ): void {
191 $this->rteSupport = array(
192 "obj_id" => $obj_id,
193 "obj_type" => $obj_type,
194 "module" => $module,
195 'cfg_template' => $cfg_template,
196 'hide_switch' => $hide_switch,
197 'version' => $version
198 );
199 }
200
201 public function removeRTESupport(): void
202 {
203 $this->rteSupport = array();
204 }
205
206 public function setRteTags(array $a_rtetags): void
207 {
208 $this->rtetags = $a_rtetags;
209 }
210
211 public function getRteTags(): array
212 {
213 return $this->rtetags;
214 }
215
220 public function setRteTagSet(string $a_set_name): void
221 {
222 $this->setRteTags($this->rte_tag_set[$a_set_name]);
223 }
224
225 public function getRteTagSet($a_set_name): array
226 {
227 return $this->rte_tag_set[$a_set_name];
228 }
229
230 public function getRteTagString(): string
231 {
232 $result = "";
233 foreach ($this->getRteTags() as $tag) {
234 $result .= "<$tag>";
235 }
236 return $result;
237 }
238
242 public function setUseTagsForRteOnly(bool $a_val): void
243 {
244 $this->use_tags_for_rte_only = $a_val;
245 }
246
247 public function getUseTagsForRteOnly(): bool
248 {
249 return $this->use_tags_for_rte_only;
250 }
251
252 public function setValueByArray(array $a_values): void
253 {
254 $this->setValue($a_values[$this->getPostVar()] ?? "");
255
256 foreach ($this->getSubItems() as $item) {
257 $item->setValueByArray($a_values);
258 }
259 }
260
261 public function checkInput(): bool
262 {
264
265 $value = $this->getInput();
266 if ($this->getRequired() && trim($value) == "") {
267 $this->setAlert($lng->txt("msg_input_is_required"));
268 return false;
269 }
270
271 if ($this->isCharLimited()) {
272 //avoid whitespace surprises. #20630, #20674
273 $ascii_whitespaces = chr(194) . chr(160);
274 $ascii_breaklines = chr(13) . chr(10);
275
276 $to_replace = array($ascii_whitespaces, $ascii_breaklines, "&lt;", "&gt;", "&amp;");
277 $replace_to = array(' ', '', "_", "_", "_");
278
279 #20630 mbstring extension is mandatory for 5.4
280 $chars_entered = mb_strlen(strip_tags(str_replace($to_replace, $replace_to, $value)));
281
282 if ($this->getMaxNumOfChars() && ($chars_entered > $this->getMaxNumOfChars())) {
283 $this->setAlert($lng->txt("msg_input_char_limit_max"));
284 return false;
285 } elseif ($this->getMinNumOfChars() && ($chars_entered < $this->getMinNumOfChars())) {
286 $this->setAlert($lng->txt("msg_input_char_limit_min"));
287 return false;
288 }
289 }
290
291 return $this->checkSubItemsInput();
292 }
293
294 public function getInput(): string
295 {
296 if ($this->usePurifier() && $this->getPurifier()) {
297 $value = $this->getPurifier()->purify($this->raw($this->getPostVar()));
298 } else {
299 $allowed = $this->getRteTagString();
300 if (isset($this->plugins["latex"]) && $this->plugins["latex"] == "latex" && !is_int(strpos($allowed, "<span>"))) {
301 $allowed .= "<span>";
302 }
303 $value = ($this->getUseRte() || !$this->getUseTagsForRteOnly())
304 ? ilUtil::stripSlashes($this->raw($this->getPostVar()), true, $allowed)
305 : $this->str($this->getPostVar());
306 }
307
308 $value = self::removeProhibitedCharacters($value);
309 return $value;
310 }
311
312 public function insert(ilTemplate $a_tpl): void
313 {
315
316 $ttpl = new ilTemplate("tpl.prop_textarea.html", true, true, "Services/Form");
317
318 if ($this->getInfo() !== '') {
319 $ttpl->setCurrentBlock('described_by_description');
320 $ttpl->setVariable('DESCRIBED_BY_DESCRIPTION_FIELD_ID', $this->getFieldId());
321 $ttpl->parseCurrentBlock();
322 }
323
324 // disabled rte
325 if ($this->getUseRte() && $this->getDisabled()) {
326 $ttpl->setCurrentBlock("disabled_rte");
327 $ttpl->setVariable("DR_VAL", $this->getValue());
328 } else {
329 if ($this->getUseRte()) {
330 $rtestring = ilRTE::_getRTEClassname();
331 $rte = new $rtestring((string) $this->rteSupport['version']);
332 $rte->setInitialWidth($this->getInitialRteWidth());
333
334 // @todo: Check this.
335 $rte->addPlugin("emoticons");
336 foreach ($this->plugins as $plugin) {
337 if (strlen($plugin)) {
338 $rte->addPlugin($plugin);
339 }
340 }
341 foreach ($this->removeplugins as $plugin) {
342 if (strlen($plugin)) {
343 $rte->removePlugin($plugin);
344 }
345 }
346
347 foreach ($this->buttons as $button) {
348 if (strlen($button)) {
349 $rte->addButton($button);
350 }
351 }
352
353 $rte->disableButtons($this->getDisabledButtons());
354
355 if ($this->getRTERootBlockElement() !== null) {
356 $rte->setRTERootBlockElement($this->getRTERootBlockElement());
357 }
358
359 if (count($this->rteSupport) >= 3) {
360 $rte->addRTESupport($this->rteSupport["obj_id"], $this->rteSupport["obj_type"], $this->rteSupport["module"], false, $this->rteSupport['cfg_template'], $this->rteSupport['hide_switch']);
361 } else {
362 // disable all plugins for mini-tagset
363 if (!array_diff($this->getRteTags(), $this->getRteTagSet("mini"))) {
364 $rte->removeAllPlugins();
365
366 // #13603 - "paste from word" is essential
367 $rte->addPlugin("paste");
368 //Add plugins 'lists', 'code' and 'link': in tinymce 3 it wasnt necessary to configure these plugins
369 $rte->addPlugin("lists");
370 $rte->addPlugin("link");
371 $rte->addPlugin("code");
372
373 if (method_exists($rte, 'removeAllContextMenuItems')) {
374 $rte->removeAllContextMenuItems(); //https://github.com/ILIAS-eLearning/ILIAS/pull/3088#issuecomment-805830050
375 }
376
377 // #11980 - p-tag is mandatory but we do not want the icons it comes with
378 $rte->disableButtons(array("anchor", "alignleft", "aligncenter",
379 "alignright", "alignjustify", "formatselect", "removeformat",
380 "cut", "copy", "paste", "pastetext")); // JF, 2013-12-09
381 }
382 $rte->addCustomRTESupport(0, "", $this->getRteTags());
383 }
384
385 $ttpl->touchBlock("prop_ta_w");
386 } else {
387 $ttpl->touchBlock("no_rteditor");
388
389 if ($this->getCols() > 5) {
390 $ttpl->setCurrentBlock("prop_ta_c");
391 $ttpl->setVariable("COLS", $this->getCols());
392 $ttpl->parseCurrentBlock();
393 } else {
394 $ttpl->touchBlock("prop_ta_w");
395 }
396 }
397 $ttpl->setCurrentBlock("prop_textarea");
398 $ttpl->setVariable("ROWS", $this->getRows());
399 $ttpl->setVariable("POST_VAR", $this->getPostVar());
400 $ttpl->setVariable("ID", $this->getFieldId());
401 if ($this->getDisabled()) {
402 $ttpl->setVariable('DISABLED', 'disabled="disabled" ');
403 }
404 $ttpl->setVariable("PROPERTY_VALUE", ilLegacyFormElementsUtil::prepareFormOutput($this->getValue()));
405
406 if ($this->getRequired()) {
407 $ttpl->setVariable("REQUIRED", "required=\"required\"");
408 }
409
410 if ($this->isCharLimited()) {
411 $ttpl->setVariable("MAXCHARS", $this->getMaxNumOfChars());
412 $ttpl->setVariable("MINCHARS", $this->getMinNumOfChars());
413
414 $lng->toJS("form_chars_remaining");
415 }
416 }
417 $ttpl->parseCurrentBlock();
418
419 if ($this->isCharLimited()) {
420 $ttpl->setVariable("FEEDBACK_MAX_LIMIT", $this->getMaxNumOfChars());
421 $ttpl->setVariable("FEEDBACK_ID", $this->getFieldId());
422 $ttpl->setVariable("CHARS_REMAINING", $lng->txt("form_chars_remaining"));
423 }
424
425 if ($this->getDisabled()) {
426 $ttpl->setVariable(
427 "HIDDEN_INPUT",
428 $this->getHiddenTag($this->getPostVar(), $this->getValue())
429 );
430 }
431 $a_tpl->setCurrentBlock("prop_generic");
432 $a_tpl->setVariable("PROP_GENERIC", $ttpl->get());
433 $a_tpl->parseCurrentBlock();
434 }
435
441 public function usePurifier(bool $a_flag = null)
442 {
443 if (null === $a_flag) {
444 return $this->usePurifier;
445 }
446
447 $this->usePurifier = $a_flag;
448 return $this;
449 }
450
454 public function setPurifier(ilHtmlPurifierInterface $Purifier): self
455 {
456 $this->Purifier = $Purifier;
457 return $this;
458 }
459
461 {
462 return $this->Purifier;
463 }
464
465 public function setRTERootBlockElement(?string $a_root_block_element): self
466 {
467 $this->root_block_element = $a_root_block_element;
468 return $this;
469 }
470
471 public function getRTERootBlockElement(): ?string
472 {
473 return $this->root_block_element;
474 }
475
481 public function disableButtons($a_button): self
482 {
483 if (is_array($a_button)) {
484 $this->disabled_buttons = array_unique(array_merge($this->disabled_buttons, $a_button));
485 } else {
486 $this->disabled_buttons = array_unique(array_merge($this->disabled_buttons, array($a_button)));
487 }
488 return $this;
489 }
490
494 public function getDisabledButtons(bool $as_array = true)
495 {
496 if (!$as_array) {
497 return implode(',', $this->disabled_buttons);
498 } else {
499 return $this->disabled_buttons;
500 }
501 }
502
503 public function getInitialRteWidth(): int
504 {
505 return $this->initial_rte_width;
506 }
507
508 public function setInitialRteWidth(int $initial_rte_width): void
509 {
510 $this->initial_rte_width = $initial_rte_width;
511 }
512
513 public function isCharLimited(): bool
514 {
515 if ($this->getMaxNumOfChars() || $this->getMinNumOfChars()) {
516 return true;
517 }
518
519 return false;
520 }
521}
$version
Definition: plugin.php:24
setVariable($variable, $value='')
Sets a variable value.
Definition: IT.php:514
static prepareFormOutput($a_str, bool $a_strip=false)
static _getRTEClassname()
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
special template class to simplify handling of ITX/PEAR
setCurrentBlock(string $part=ilGlobalTemplateInterface::DEFAULT_BLOCK)
parseCurrentBlock(string $part=ilGlobalTemplateInterface::DEFAULT_BLOCK)
This class represents a text area property in a property form.
removeButton(string $a_button)
removePlugin(string $a_plugin)
disableButtons($a_button)
Sets buttons which should be disabled in TinyMCE.
setUseTagsForRteOnly(bool $a_val)
Set use tags for RTE only (default is true)
setPurifier(ilHtmlPurifierInterface $Purifier)
Setter for the html purifier.
__construct(string $a_title="", string $a_postvar="")
usePurifier(bool $a_flag=null)
Setter/Getter for the html purifier usage.
setRTESupport(int $obj_id, string $obj_type, string $module, ?string $cfg_template=null, bool $hide_switch=false, ?string $version=null)
Set RTE support for a special module.
getDisabledButtons(bool $as_array=true)
setRteTagSet(string $a_set_name)
setValueByArray(array $a_values)
ilHtmlPurifierInterface $Purifier
setInitialRteWidth(int $initial_rte_width)
checkInput()
Check input, strip slashes etc.
setUseRte(bool $a_usert, string $version='')
setRTERootBlockElement(?string $a_root_block_element)
static stripSlashes(string $a_str, bool $a_strip_html=true, string $a_allow="")
global $DIC
Definition: feed.php:28
Interface for html sanitizing functionality.
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
getValue()
Get the value that is displayed in the input client side.
Definition: Group.php:47
$lng