ILIAS  trunk Revision v11.0_alpha-2638-g80c1d007f79
class.ilLinkInputGUI.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
31 {
32  public const EXTERNAL_LINK_MAX_LENGTH = 200;
33  public const LIST = "list";
34  public const BOTH = "both";
35  public const INT = "int";
36  public const EXT = "ext";
37 
38  protected string $allowed_link_types = self::BOTH;
39  protected string $int_link_default_type = "RepositoryItem";
40  protected int $int_link_default_obj = 0;
41  protected array $int_link_filter_types = array("RepositoryItem");
42  protected bool $filter_white_list = true;
43  protected int $external_link_max_length = self::EXTERNAL_LINK_MAX_LENGTH;
44 
45  protected static array $iltypemap = array(
46  "page" => "PageObject",
47  "chap" => "StructureObject",
48  "term" => "GlossaryItem",
49  "wpage" => "WikiPage"
50  );
52  protected string $requested_postvar;
53  protected string $value = "";
54 
55  public function __construct(
56  string $a_title = "",
57  string $a_postvar = ""
58  ) {
59  global $DIC;
60 
61  $this->ctrl = $DIC->ctrl();
62  $this->lng = $DIC->language();
63 
64  parent::__construct($a_title, $a_postvar);
65  $this->setType("link");
66 
67  $this->obj_definition = $DIC["objDefinition"];
68 
69  $this->requested_postvar = $this->str("postvar");
70  }
71 
77  public function setAllowedLinkTypes(string $a_val): void
78  {
79  $this->allowed_link_types = $a_val;
80  }
81 
82  public function getAllowedLinkTypes(): string
83  {
85  }
86 
93  public function setInternalLinkDefault(
94  string $a_type,
95  int $a_obj = 0
96  ): void {
97  $this->int_link_default_type = $a_type;
98  $this->int_link_default_obj = $a_obj;
99  }
100 
106  public function setInternalLinkFilterTypes(array $a_val): void
107  {
108  $this->int_link_filter_types = $a_val;
109  }
110 
116  public static function getTypeToAttrType(): array
117  {
118  return self::$iltypemap;
119  }
120 
126  public static function getAttrTypeToType(): array
127  {
128  return array_flip(self::$iltypemap);
129  }
130 
136  public function setFilterWhiteList(bool $a_val): void
137  {
138  $this->filter_white_list = $a_val;
139  }
140 
141  public function getFilterWhiteList(): bool
142  {
144  }
145 
149  public function setExternalLinkMaxLength(int $a_max): void
150  {
151  $this->external_link_max_length = $a_max;
152  }
153 
154  public function getExternalLinkMaxLength(): int
155  {
157  }
158 
159  public function executeCommand()
160  {
161  $ilCtrl = $this->ctrl;
162  $lng = $this->lng;
163 
164  $next_class = $ilCtrl->getNextClass($this);
165  $cmd = $ilCtrl->getCmd();
166 
167  $ret = "";
168  switch ($next_class) {
169  case "ilinternallinkgui":
170  $lng->loadLanguageModule("content");
171  $link_gui = new ilInternalLinkGUI(
172  $this->int_link_default_type,
173  $this->int_link_default_obj
174  );
175  foreach ($this->int_link_filter_types as $t) {
176  $link_gui->filterLinkType($t);
177  }
178  $link_gui->setFilterWhiteList($this->getFilterWhiteList());
179 
180  $ret = $ilCtrl->forwardCommand($link_gui);
181  break;
182 
183  default:
184  var_dump($cmd);
185  //exit();
186  }
187 
188  return $ret;
189  }
190 
195  public function setValue(string $a_value): void
196  {
197  $this->value = $a_value;
198  }
199 
204  public function getValue(): string
205  {
206  return $this->value;
207  }
208 
209  public function setValueByArray(array $a_values): void
210  {
211  switch ($a_values[$this->getPostVar() . "_mode"] ?? null) {
212  case "int":
213  if ($a_values[$this->getPostVar() . "_ajax_type"] &&
214  $a_values[$this->getPostVar() . "_ajax_id"]) {
215  $val = $a_values[$this->getPostVar() . "_ajax_type"] . "|" .
216  $a_values[$this->getPostVar() . "_ajax_id"];
217  if ($a_values[$this->getPostVar() . "_ajax_target"] != "") {
218  $val .= "|" . $a_values[$this->getPostVar() . "_ajax_target"];
219  }
220  $this->setValue($val);
221  }
222  break;
223 
224  case "no":
225  break;
226 
227  default:
228  if ($a_values[$this->getPostVar()]) {
229  $this->setValue($a_values[$this->getPostVar()]);
230  }
231  break;
232  }
233  }
234 
239  public function checkInput(): bool
240  {
241  $lng = $this->lng;
242 
243  // debugging
244  // return false;
245 
246  $mode_type = $this->str($this->getPostVar() . "_mode_type");
247  $ajax_type = $this->str($this->getPostVar() . "_ajax_type");
248  $ajax_id = $this->str($this->getPostVar() . "_ajax_id");
249  $mode = $this->str($this->getPostVar() . "_mode");
250  $value = $this->str($this->getPostVar());
251 
252  if ($this->getRequired()) {
253  if ($mode_type == "list") {
254  return true;
255  }
256 
257  switch ($mode) {
258  case "ext":
259  if (!$value) {
260  $this->setAlert($lng->txt("msg_input_is_required"));
261  return false;
262  }
263  break;
264 
265  case "int":
266  if (!$ajax_type || !$ajax_id) {
267  $this->setAlert($lng->txt("msg_input_is_required"));
268  return false;
269  }
270  break;
271 
272  case "no":
273  default:
274  $this->setAlert($lng->txt("msg_input_is_required"));
275  return false;
276  }
277  }
278 
279  return true;
280  }
281 
282  public function getInput(): string
283  {
284  $ajax_type = $this->str($this->getPostVar() . "_ajax_type");
285  $ajax_id = $this->str($this->getPostVar() . "_ajax_id");
286  $ajax_target = $this->str($this->getPostVar() . "_ajax_target");
287  $mode = $this->str($this->getPostVar() . "_mode");
288  $value = $this->str($this->getPostVar());
289 
290  if ($mode == "int") {
291  // overwriting post-data so getInput() will work
292  $val = $ajax_type . "|" . $ajax_id;
293  if ($ajax_target != "") {
294  $val .= "|" . $ajax_target;
295  }
296  return $val;
297  } elseif ($mode == "no") {
298  return "";
299  }
300  return $value;
301  }
302 
303  public function render(): string
304  {
305  $lng = $this->lng;
306  $ilCtrl = $this->ctrl;
307 
308  $ti = null;
309  $ne = null;
310  $hidden_type = null;
311  $hidden_id = null;
312  $hidden_target = null;
313 
314  // parse settings
315  $has_int = $has_ext = $has_radio = $has_list = false;
316  switch ($this->getAllowedLinkTypes()) {
317  case self::EXT:
318  $has_ext = true;
319  break;
320 
321  case self::INT:
322  $has_int = true;
323  break;
324 
325  case self::BOTH:
326  $has_int = true;
327  $has_ext = true;
328  $has_radio = true;
329  break;
330 
331  case self::LIST:
332  $has_int = true;
333  $has_ext = true;
334  $has_radio = true;
335  $has_list = true;
336  break;
337  }
338  if (!$this->getRequired()) {
339  // see #0021274
340  $has_radio = true;
341  }
342 
343  // external
344  if ($has_ext) {
345  $title = $has_radio ? $lng->txt("url") : "";
346 
347  // external
348  $ti = new ilTextInputGUI($title, $this->getPostVar());
349  $ti->setMaxLength($this->getExternalLinkMaxLength());
350  }
351 
352  $itpl = new ilTemplate('tpl.prop_link.html', true, true, 'components/ILIAS/Form');
353 
354  // internal
355  if ($has_int) {
356  $ilCtrl->setParameterByClass("ilformpropertydispatchgui", "postvar", $this->getPostVar());
357  $link = array(get_class($this->getParentForm()), "ilformpropertydispatchgui", get_class($this), "ilinternallinkgui");
358  $link = $ilCtrl->getLinkTargetByClass($link, "", '', true, false);
359  $ilCtrl->setParameterByClass("ilformpropertydispatchgui", "postvar", $this->requested_postvar);
360 
361  $no_disp_class = (strpos($this->getValue(), "|"))
362  ? ""
363  : " ilNoDisplay";
364 
365  $itpl->setVariable("VAL_ID", $this->getPostVar());
366  $itpl->setVariable("URL_EDIT", $link);
367  $itpl->setVariable("TXT_EDIT", $lng->txt("form_get_link"));
368  $itpl->setVariable("CSS_REMOVE", $no_disp_class);
369  $itpl->setVariable("TXT_REMOVE", $lng->txt("remove"));
370 
371  $ne = new ilNonEditableValueGUI($lng->txt("object"), $this->getPostVar() . "_val", true);
372 
373  // hidden field for selected value
374  $hidden_type = new ilHiddenInputGUI($this->getPostVar() . "_ajax_type");
375  $hidden_id = new ilHiddenInputGUI($this->getPostVar() . "_ajax_id");
376  $hidden_target = new ilHiddenInputGUI($this->getPostVar() . "_ajax_target");
377  }
378 
379  // mode
380  if ($has_radio) {
381  // BT 35578: link input might be required (so $has_radio = true), but might only be internal
382  if ($has_ext) {
383  $ext = new ilRadioOption($lng->txt("form_link_external"), "ext");
384  $ext->addSubItem($ti);
385  }
386 
387  if ($has_int) {
388  $int = new ilRadioOption($lng->txt("form_link_internal"), "int");
389  $int->addSubItem($ne);
390  }
391  $mode = new ilRadioGroupInputGUI("", $this->getPostVar() . "_mode");
392  $mode->setParentForm($this->getParentForm());
393  if (!$this->getRequired()) {
394  $no = new ilRadioOption($lng->txt("form_no_link"), "no");
395  $mode->addOption($no);
396  }
397  // BT 35578: link input might be required (so $has_radio = true), but might only be internal
398  if ($has_ext) {
399  $mode->addOption($ext);
400  }
401  if ($has_int) {
402  $mode->addOption($int);
403  }
404  } else {
405  $mode = new ilHiddenInputGUI($this->getPostVar() . "_mode");
406  if ($has_int) {
407  $mode->setValue("int");
408  } else {
409  $mode->setValue("ext");
410  }
411  }
412 
413  // list mode
414  if ($has_list) {
415  $mode_type = new ilRadioGroupInputGUI("", $this->getPostVar() . "_mode_type");
416  $mode_single = new ilRadioOption($lng->txt("webr_link_type_single"), "single");
417  $mode_type->addOption($mode_single);
418  $mode_list = new ilRadioOption($lng->txt("webr_link_type_list"), "list");
419  $mode_type->addOption($mode_list);
420  $mode = new ilRadioGroupInputGUI($lng->txt("webr_link_target"), $this->getPostVar() . "_mode");
421  if (!$this->getRequired()) {
422  $no = new ilRadioOption($lng->txt("form_no_link"), "no");
423  $mode->addOption($no);
424  }
425  $ext = new ilRadioOption($lng->txt("form_link_external"), "ext");
426  $ext->addSubItem($ti);
427  $int = new ilRadioOption($lng->txt("form_link_internal"), "int");
428  $int->addSubItem($ne);
429  $mode->addOption($ext);
430  $mode->addOption($int);
431  $mode_single->addSubItem($mode);
432  }
433 
434  // value
435  $value = $this->getValue();
436  if ($value) {
437  // #15647
438  if ($has_int && self::isInternalLink($value)) {
439  $mode->setValue("int");
440 
441  $value_trans = self::getTranslatedValue($value);
442 
443  $value = explode("|", $value);
444  $hidden_type->setValue($value[0]);
445  $hidden_id->setValue($value[1]);
446  $hidden_target->setValue($value[2] ?? "");
447 
448  $itpl->setVariable("VAL_OBJECT_TYPE", $value_trans["type"]);
449  $itpl->setVariable("VAL_OBJECT_NAME", $value_trans["name"]);
450  if (($value[2] ?? "") != "") {
451  $itpl->setVariable("VAL_TARGET_FRAME", "(" . $value[2] . ")");
452  }
453  } elseif ($has_ext) {
454  $mode->setValue("ext");
455 
456  $ti->setValue($value);
457  }
458  } elseif (!$this->getRequired()) {
459  $mode->setValue("no");
460  }
461 
462  // #10185 - default for external urls
463  if ($has_ext && !$ti->getValue()) {
464  $ti->setValue("https://");
465  }
466 
467  if ($has_int) {
468  $ne->setValue($itpl->get());
469  }
470 
471  // to html
472  if ($has_radio) {
473  $html = $mode->render();
474  } else {
475  $html = $mode->getToolbarHTML();
476 
477  if ($has_ext) {
478  $html .= $ti->getToolbarHTML();
479  } elseif ($has_int) {
480  $html .= $ne->render() .
481  '<div class="help-block">' . $ne->getInfo() . '</div>';
482  }
483  }
484  if ($has_list) {
485  $html = $mode_type->render();
486  }
487 
488  // js for internal link
489  if ($has_int) {
490  $html .= $hidden_type->getToolbarHTML() .
491  $hidden_id->getToolbarHTML() .
492  $hidden_target->getToolbarHTML();
493  }
494 
495  return $html;
496  }
497 
498  public function getContentOutsideFormTag(): string
499  {
500  if ($this->getAllowedLinkTypes() == self::INT ||
501  $this->getAllowedLinkTypes() == self::BOTH ||
502  $this->getAllowedLinkTypes() == self::LIST) {
503  // as the ajax-panel uses a form it has to be outside of the parent form!
505  }
506  return "";
507  }
508 
509  public static function isInternalLink(string $a_value): bool
510  {
511  if (strpos($a_value, "|")) {
512  $parts = explode("|", $a_value);
513  if (sizeof($parts) == 2 || sizeof($parts) == 3) {
514  // numeric id
515  if (is_numeric($parts[1])) {
516  // simple type
517  if (preg_match("/^[a-zA-Z_]+$/", $parts[0])) {
518  return true;
519  }
520  }
521  }
522  }
523  return false;
524  }
525 
526  public static function getTranslatedValue(string $a_value): array
527  {
528  global $DIC;
529 
530  $lng = $DIC->language();
531 
532  $value = explode("|", $a_value);
533  if ($value === false || $value === []) {
534  return [];
535  }
536  switch ($value[0]) {
537  case "media":
538  $type = $lng->txt("obj_mob");
539  $name = ilObject::_lookupTitle((int) $value[1]);
540  break;
541 
542  case "page":
543  $type = $lng->txt("obj_pg");
544  $name = ilLMPageObject::_lookupTitle((int) $value[1]);
545  break;
546 
547  case "chap":
548  $type = $lng->txt("obj_st");
549  $name = ilStructureObject::_lookupTitle((int) $value[1]);
550  break;
551 
552  case "term":
553  $type = $lng->txt("term");
554  $name = ilGlossaryTerm::_lookGlossaryTerm((int) $value[1]);
555  break;
556 
557  case "wpage":
558  $type = $lng->txt("cont_wiki_page");
559  $name = ilWikiPage::lookupTitle((int) $value[1]);
560  break;
561 
562  default:
563  $type = $lng->txt("obj_" . $value[0]);
564  $name = ilObject::_lookupTitle(ilObject::_lookupObjId((int) $value[1]));
565  break;
566  }
567  return array("type" => $type, "name" => $name);
568  }
569 
570  public function insert(ilTemplate $a_tpl): void
571  {
572  $html = $this->render();
573 
574  $a_tpl->setCurrentBlock("prop_generic");
575  $a_tpl->setVariable("PROP_GENERIC", $html);
576  $a_tpl->parseCurrentBlock();
577  }
578 
584  public function getIntLinkAttributes(): ?array
585  {
586  $val = explode("|", $this->getInput());
587  $ret = null;
588  $type = "";
589  $target = "";
590  if (self::isInternalLink($this->getInput())) {
591  $target_frame = $val[2] ?? "";
592  $map = self::getTypeToAttrType();
593  if (isset($map[$val[0]])) {
594  $type = $map[$val[0]];
595  $target_type = $val[0];
596  if ($val[0] == "chap") {
597  $target_type = "st";
598  }
599  if ($val[0] == "term") {
600  $target_type = "git";
601  }
602  if ($val[0] == "page") {
603  $target_type = "pg";
604  }
605  $target = "il__" . $target_type . "_" . $val[1];
606  } elseif ($this->obj_definition->isRBACObject($val[0])) {
607  $type = "RepositoryItem";
608  $target = "il__obj_" . $val[1];
609  }
610  if ($type != "") {
611  $ret = array(
612  "Target" => $target,
613  "Type" => $type,
614  "TargetFrame" => $target_frame
615  );
616  }
617  }
618  return $ret;
619  }
620 
622  string $a_type,
623  string $a_target,
624  string $a_target_frame = ""
625  ): void {
626  $t = explode("_", $a_target);
627  $target_id = ($t[3] ?? "");
628  $type = "";
629  $map = self::getAttrTypeToType();
630  if ($a_type == "RepositoryItem") {
631  $type = ilObject::_lookupType((int) $target_id, true);
632  } elseif (isset($map[$a_type])) {
633  $type = $map[$a_type];
634  }
635  if ($type != "" && $target_id != "") {
636  $val = $type . "|" . $target_id;
637  if ($a_target_frame != "") {
638  $val .= "|" . $a_target_frame;
639  }
640  $this->setValue($val);
641  }
642  }
643 
644  public function getOnloadCode(): array
645  {
646  return [
648  ];
649  }
650 }
parseCurrentBlock(string $part=ilGlobalTemplateInterface::DEFAULT_BLOCK)
static array $iltypemap
This class represents an option in a radio group.
insert(ilTemplate $a_tpl)
setValueByArray(array $a_values)
static getInitHTML(string $a_url)
Get initialisation HTML to use internal link editing.
setAllowedLinkTypes(string $a_val)
Set allowed link types (LIST, BOTH, INT, EXT)
txt(string $a_topic, string $a_default_lang_fallback_mod="")
gets the text for a given topic if the topic is not in the list, the topic itself with "-" will be re...
if($clientAssertionType !='urn:ietf:params:oauth:client-assertion-type:jwt-bearer'|| $grantType !='client_credentials') $parts
Definition: ltitoken.php:61
checkInput()
Check input, strip slashes etc.
static getAttrTypeToType()
Get internal types to xml attribute types map (reverse)
static lookupTitle(int $a_page_id, string $lang="-")
setInternalLinkFilterTypes(array $a_val)
Set internal link filter types.
static getTranslatedValue(string $a_value)
setFilterWhiteList(bool $a_val)
Set filter white list.
static getOnloadCode(string $a_url)
setValueByIntLinkAttributes(string $a_type, string $a_target, string $a_target_frame="")
loadLanguageModule(string $a_module)
Load language module.
Internal link selector.
setInternalLinkDefault(string $a_type, int $a_obj=0)
Set internal link default.
static _lookupObjId(int $ref_id)
static _lookupTitle(int $a_obj_id)
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
This class represents a hidden form property in a property form.
static getTypeToAttrType()
Get internal types to xml attribute types map.
This class represents a property in a property form.
setVariable($variable, $value='')
Sets a variable value.
Definition: IT.php:544
static _lookupTitle(int $obj_id)
__construct(string $a_title="", string $a_postvar="")
static _lookGlossaryTerm(int $term_id)
get glossary term
global $DIC
Definition: shib_login.php:26
setValue(string $a_value)
Set Value.
getIntLinkAttributes()
Get value as internal link attributes.
setCurrentBlock(string $part=ilGlobalTemplateInterface::DEFAULT_BLOCK)
static isInternalLink(string $a_value)
__construct(Container $dic, ilPlugin $plugin)
static _lookupType(int $id, bool $reference=false)
ilObjectDefinition $obj_definition
setExternalLinkMaxLength(int $a_max)
This class represents a external and/or internal link in a property form.