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