ILIAS  release_8 Revision v8.19
All Data Structures Namespaces Files Functions Variables Modules Pages
class.ilUtil.php
Go to the documentation of this file.
1 <?php
2 
23 
37 class ilUtil
38 {
44  public static function getImageTagByType(string $a_type, string $a_path, bool $a_big = false): string
45  {
46  global $DIC;
47 
48  $lng = $DIC->language();
49 
50  $size = ($a_big)
51  ? "big"
52  : "small";
53 
54  $filename = ilObject::_getIcon(0, $size, $a_type);
55 
56  return "<img src=\"" . $filename . "\" alt=\"" . $lng->txt("obj_" . $a_type) . "\" title=\"" . $lng->txt(
57  "obj_" . $a_type
58  ) . "\" border=\"0\" vspace=\"0\"/>";
59  }
60 
67  public static function getImagePath(
68  string $img,
69  string $module_path = "",
70  string $mode = "output",
71  bool $offline = false
72  ): string {
73  global $DIC;
74 
75  $styleDefinition = null;
76  if (isset($DIC["styleDefinition"])) {
77  $styleDefinition = $DIC["styleDefinition"];
78  }
79 
80  if (is_int(strpos($_SERVER["PHP_SELF"], "setup.php"))) {
81  $module_path = "..";
82  }
83  if ($module_path != "") {
84  $module_path = "/" . $module_path;
85  }
86 
87  // default image
88  $default_img = "." . $module_path . "/templates/default/images/" . $img;
89 
90  // use ilStyleDefinition instead of account to get the current skin and style
91  $current_skin = ilStyleDefinition::getCurrentSkin();
92  $current_style = ilStyleDefinition::getCurrentStyle();
93 
94  if (is_object($styleDefinition)) {
95  $image_dir = $styleDefinition->getImageDirectory($current_style);
96  }
97  $skin_img = "";
98  if ($current_skin == "default") {
99  $user_img = "." . $module_path . "/templates/default/" . $image_dir . "/" . $img;
100  $skin_img = "." . $module_path . "/templates/default/images/" . $img;
101  } elseif (is_object($styleDefinition) && $current_skin != "default") {
102  $user_img = "./Customizing/global/skin/" .
103  $current_skin . $module_path . "/" . $image_dir . "/" . $img;
104  $skin_img = "./Customizing/global/skin/" .
105  $current_skin . $module_path . "/images/" . $img;
106  }
107 
108 
109  if ($offline) {
110  return "./images/" . $img;
111  } elseif (@file_exists($user_img) && $image_dir != "") {
112  return $user_img; // found image for skin and style
113  } elseif (file_exists($skin_img)) {
114  return $skin_img; // found image in skin/images
115  }
116 
117  return $default_img; // take image in default
118  }
119 
126  public static function getHtmlPath(string $relative_path): string
127  {
128  if (substr($relative_path, 0, 2) == './') {
129  $relative_path = (substr($relative_path, 1));
130  }
131  if (substr($relative_path, 0, 1) != '/') {
132  $relative_path = '/' . $relative_path;
133  }
134  $htmlpath = ILIAS_HTTP_PATH . $relative_path;
135  return $htmlpath;
136  }
137 
148  public static function getStyleSheetLocation(
149  string $mode = "output",
150  string $a_css_name = "",
151  string $a_css_location = ""
152  ): string {
153  global $DIC;
154 
155  $ilSetting = $DIC->settings();
156 
157  // add version as parameter to force reload for new releases
158  // use ilStyleDefinition instead of account to get the current style
159  $stylesheet_name = (strlen($a_css_name))
160  ? $a_css_name
162  if (strlen($a_css_location) && (strcmp(substr($a_css_location, -1), "/") != 0)) {
163  $a_css_location = $a_css_location . "/";
164  }
165 
166  $filename = "";
167  // use ilStyleDefinition instead of account to get the current skin
168  if (ilStyleDefinition::getCurrentSkin() != "default") {
169  $filename = "./Customizing/global/skin/" . ilStyleDefinition::getCurrentSkin(
170  ) . "/" . $a_css_location . $stylesheet_name;
171  }
172  if (strlen($filename) == 0 || !file_exists($filename)) {
173  $filename = "./" . $a_css_location . "templates/default/" . $stylesheet_name;
174  }
175  $skin_version_appendix = "";
176  if ($mode !== "filesystem") {
177  // use version from template xml to force reload on changes
179  $skin_version = $skin->getVersion();
180  $skin_version_appendix .= ($skin_version !== '' ? str_replace(".", "-", $skin_version) : '0');
181  $skin_version_appendix = "?skin_version=" . $skin_version_appendix;
182  }
183  return $filename . $skin_version_appendix;
184  }
185 
191  public static function getNewContentStyleSheetLocation(string $mode = "output"): string
192  {
193 
194  // use ilStyleDefinition instead of account to get the current skin and style
195  if (ilStyleDefinition::getCurrentSkin() == "default") {
196  $in_style = "./templates/" . ilStyleDefinition::getCurrentSkin() . "/"
197  . ilStyleDefinition::getCurrentStyle() . "_cont.css";
198  } else {
199  $in_style = "./Customizing/global/skin/" . ilStyleDefinition::getCurrentSkin() . "/"
200  . ilStyleDefinition::getCurrentStyle() . "_cont.css";
201  }
202 
203  if (is_file("./" . $in_style)) {
204  return $in_style;
205  } else {
206  return "templates/default/delos_cont.css";
207  }
208  }
209 
216  public static function switchColor(int $a_num, string $a_css1, string $a_css2): string
217  {
218  if (!($a_num % 2)) {
219  return $a_css1;
220  } else {
221  return $a_css2;
222  }
223  }
224 
229  public static function makeClickable(string $a_text, bool $detectGotoLinks = false): string
230  {
231  global $DIC;
232 
233  $ret = $DIC->refinery()->string()->makeClickable()->transform($a_text);
234 
235  if ($detectGotoLinks) {
236  $goto = '<a[^>]*href="(' . str_replace('@', '\@', ILIAS_HTTP_PATH) . '/goto';
237  $regExp = $goto . '.php\?target=\w+_(\d+)[^"]*)"[^>]*>[^<]*</a>';
238  $ret = preg_replace_callback(
239  '@' . $regExp . '@i',
240  [self::class, 'replaceLinkProperties'],
241  $ret
242  );
243 
244  // Edited this regex to allow multiple links in $ret: .* to [^"><]*.
245  $regExp = $goto . '_[^"><]*[a-z0-9]+_([0-9]+)\.html)"[^>]*>[^<]*</a>';
246  $ret = preg_replace_callback(
247  '@' . $regExp . '@i',
248  [self::class, 'replaceLinkProperties'],
249  $ret
250  );
251  }
252 
253  return $ret;
254  }
255 
256  private static function replaceLinkProperties(array $matches): string
257  {
258  global $DIC;
259  $cache = $DIC['ilObjDataCache'];
260 
261  $link = $matches[0];
262  $ref_id = (int) $matches[2];
263  if ($ref_id > 0) {
264  $obj_id = $cache->lookupObjId($ref_id);
265  if ($obj_id > 0) {
266  $title = $cache->lookupTitle($obj_id);
267  $link = '<a href="' . $matches[1] . '" target="_self">' . $title . '</a>';
268  }
269  }
270 
271  return $link;
272  }
273 
283  public static function is_email(
284  string $a_email,
285  ilMailRfc822AddressParserFactory $mailAddressParserFactory = null
286  ): bool {
287  if ($mailAddressParserFactory === null) {
288  $mailAddressParserFactory = new ilMailRfc822AddressParserFactory();
289  }
290 
291  try {
292  $parser = $mailAddressParserFactory->getParser($a_email);
293  $addresses = $parser->parse();
294  return count($addresses) == 1 && $addresses[0]->getHost() != ilMail::ILIAS_HOST;
295  } catch (ilException $e) {
296  return false;
297  }
298  }
299 
303  public static function isLogin(string $a_login): bool
304  {
305  if (empty($a_login)) {
306  return false;
307  }
308 
309  if (strlen($a_login) < 3) {
310  return false;
311  }
312 
313  // FIXME - If ILIAS is configured to use RFC 822
314  // compliant mail addresses we should not
315  // allow the @ character.
316  if (!preg_match("/^[A-Za-z0-9_\.\+\*\@!\$\%\~\-]+$/", $a_login)) {
317  return false;
318  }
319 
320  return true;
321  }
322 
329  public static function img(
330  string $a_src,
331  ?string $a_alt = null,
332  $a_width = "",
333  $a_height = "",
334  $a_border = 0,
335  $a_id = "",
336  $a_class = ""
337  ) {
338  $img = '<img src="' . $a_src . '"';
339  if (!is_null($a_alt)) {
340  $img .= ' alt="' . htmlspecialchars($a_alt) . '"';
341  }
342  if ($a_width != "") {
343  $img .= ' width="' . htmlspecialchars($a_width) . '"';
344  }
345  if ($a_height != "") {
346  $img .= ' height="' . htmlspecialchars($a_height) . '"';
347  }
348  if ($a_class != "") {
349  $img .= ' class="' . $a_class . '"';
350  }
351  if ($a_id != "") {
352  $img .= ' id="' . $a_id . '"';
353  }
354  $img .= ' />';
355 
356  return $img;
357  }
358 
362  public static function deliverData(
363  string $a_data,
364  string $a_filename,
365  string $mime = "application/octet-stream"
366  ): void {
367  global $DIC;
368  $delivery = new Delivery(
369  Delivery::DIRECT_PHP_OUTPUT,
370  $DIC->http()
371  );
372  $delivery->setMimeType($mime);
373  $delivery->setSendMimeType(true);
374  $delivery->setDisposition(Delivery::DISP_ATTACHMENT);
375  $delivery->setDownloadFileName($a_filename);
376  $delivery->setConvertFileNameToAsci(true);
377  $repsonse = $DIC->http()->response()->withBody(Streams::ofString($a_data));
378  $DIC->http()->saveResponse($repsonse);
379  $delivery->deliver();
380  }
381 
385  public static function appendUrlParameterString(string $a_url, string $a_par, bool $xml_style = false): string
386  {
387  $amp = $xml_style
388  ? "&amp;"
389  : "&";
390 
391  $url = (is_int(strpos($a_url, "?")))
392  ? $a_url . $amp . $a_par
393  : $a_url . "?" . $a_par;
394 
395  return $url;
396  }
397 
401  public static function stripSlashes(string $a_str, bool $a_strip_html = true, string $a_allow = ""): string
402  {
403  if (ini_get("magic_quotes_gpc")) {
404  $a_str = stripslashes($a_str);
405  }
406 
407  return ilUtil::secureString($a_str, $a_strip_html, $a_allow);
408  }
409 
413  public static function stripOnlySlashes(string $a_str): string
414  {
415  if (ini_get("magic_quotes_gpc")) {
416  $a_str = stripslashes($a_str);
417  }
418 
419  return $a_str;
420  }
421 
425  public static function secureString(string $a_str, bool $a_strip_html = true, string $a_allow = ""): string
426  {
427  // check whether all allowed tags can be made secure
428  $only_secure = true;
429  $allow_tags = explode(">", $a_allow);
430  $sec_tags = ilUtil::getSecureTags();
431  $allow_array = [];
432  foreach ($allow_tags as $allow) {
433  if ($allow != "") {
434  $allow = str_replace("<", "", $allow);
435 
436  if (!in_array($allow, $sec_tags)) {
437  $only_secure = false;
438  }
439  $allow_array[] = $allow;
440  }
441  }
442 
443  // default behaviour: allow only secure tags 1:1
444  if (($only_secure || $a_allow == "") && $a_strip_html) {
445  if ($a_allow === "") {
446  $allow_array = ["b",
447  "i",
448  "strong",
449  "em",
450  "code",
451  "cite",
452  "gap",
453  "sub",
454  "sup",
455  "pre",
456  "strike",
457  "bdo"
458  ];
459  }
460 
461  // this currently removes parts of strings like "a <= b"
462  // because "a <= b" is treated like "<spam onclick='hurt()'>ss</spam>"
463  $a_str = ilUtil::maskSecureTags($a_str, $allow_array);
464  $a_str = strip_tags($a_str); // strip all other tags
465  $a_str = ilUtil::unmaskSecureTags($a_str, $allow_array);
466 
467  // a possible solution could be something like:
468  // $a_str = str_replace("<", "&lt;", $a_str);
469  // $a_str = str_replace(">", "&gt;", $a_str);
470  // $a_str = ilUtil::unmaskSecureTags($a_str, $allow_array);
471  //
472  // output would be ok then, but input fields would show
473  // "a &lt;= b" for input "a <= b" if data is brought back to a form
474  } else {
475  // only for scripts, that need to allow more/other tags and parameters
476  if ($a_strip_html) {
477  $a_str = ilUtil::stripScriptHTML($a_str, $a_allow);
478  }
479  }
480 
481  return $a_str;
482  }
483 
484  public static function getSecureTags(): array
485  {
486  return ["strong",
487  "em",
488  "u",
489  "strike",
490  "ol",
491  "li",
492  "ul",
493  "p",
494  "div",
495  "i",
496  "b",
497  "code",
498  "sup",
499  "sub",
500  "pre",
501  "gap",
502  "a",
503  "img",
504  "bdo"
505  ];
506  }
507 
508  private static function maskSecureTags(string $a_str, array $allow_array): string
509  {
510  foreach ($allow_array as $t) {
511  switch ($t) {
512  case "a":
513  $a_str = ilUtil::maskAttributeTag($a_str, "a", "href");
514  break;
515 
516  case "img":
517  $a_str = ilUtil::maskAttributeTag($a_str, "img", "src");
518  break;
519 
520  case "p":
521  case "div":
522  $a_str = ilUtil::maskTag($a_str, $t, [
523  ["param" => "align", "value" => "left"],
524  ["param" => "align", "value" => "center"],
525  ["param" => "align", "value" => "justify"],
526  ["param" => "align", "value" => "right"]
527  ]);
528  break;
529 
530  default:
531  $a_str = ilUtil::maskTag($a_str, $t);
532  break;
533  }
534  }
535 
536  return $a_str;
537  }
538 
539  private static function unmaskSecureTags(string $a_str, array $allow_array): string
540  {
541  foreach ($allow_array as $t) {
542  switch ($t) {
543  case "a":
544  $a_str = ilUtil::unmaskAttributeTag($a_str, "a", "href");
545  break;
546 
547  case "img":
548  $a_str = ilUtil::unmaskAttributeTag($a_str, "img", "src");
549  break;
550 
551  case "p":
552  case "div":
553  $a_str = ilUtil::unmaskTag($a_str, $t, [
554  ["param" => "align", "value" => "left"],
555  ["param" => "align", "value" => "center"],
556  ["param" => "align", "value" => "justify"],
557  ["param" => "align", "value" => "right"]
558  ]);
559  break;
560 
561  default:
562  $a_str = ilUtil::unmaskTag($a_str, $t);
563  break;
564  }
565  }
566 
567  return $a_str;
568  }
569 
573  public static function securePlainString(string $a_str): string
574  {
575  if (ini_get("magic_quotes_gpc")) {
576  return stripslashes($a_str);
577  } else {
578  return $a_str;
579  }
580  }
581 
598  public static function htmlencodePlainString(
599  string $a_str,
600  bool $a_make_links_clickable,
601  bool $a_detect_goto_links = false
602  ): string {
603  $encoded = "";
604 
605  if ($a_make_links_clickable) {
606  // Find text sequences in the plain text string which match
607  // the URI syntax rules, and pass them to ilUtil::makeClickable.
608  // Encode all other text sequences in the plain text string using
609  // htmlspecialchars and nl2br.
610  // The following expressions matches URI's as specified in RFC 2396.
611  //
612  // The expression matches URI's, which start with some well known
613  // schemes, like "http:", or with "www.". This must be followed
614  // by at least one of the following RFC 2396 expressions:
615  // - alphanum: [a-zA-Z0-9]
616  // - reserved: [;\/?:|&=+$,]
617  // - mark: [\\-_.!~*\'()]
618  // - escaped: %[0-9a-fA-F]{2}
619  // - fragment delimiter: #
620  // - uric_no_slash: [;?:@&=+$,]
621  $matches = [];
622  $numberOfMatches = preg_match_all(
623  '/(?:(?:http|https|ftp|ftps|mailto):|www\.)(?:[a-zA-Z0-9]|[;\/?:|&=+$,]|[\\-_.!~*\'()]|%[0-9a-fA-F]{2}|#|[;?:@&=+$,])+/',
624  $a_str,
625  $matches,
626  PREG_OFFSET_CAPTURE
627  );
628  $pos1 = 0;
629  $encoded = "";
630 
631  foreach ($matches[0] as $match) {
632  $matched_text = $match[0];
633  $pos2 = $match[1];
634 
635  // encode plain text
636  $encoded .= nl2br(htmlspecialchars(substr($a_str, $pos1, $pos2 - $pos1)));
637 
638  // encode URI
639  $encoded .= ilUtil::makeClickable($matched_text, $a_detect_goto_links);
640 
641 
642  $pos1 = $pos2 + strlen($matched_text);
643  }
644  if ($pos1 < strlen($a_str)) {
645  $encoded .= nl2br(htmlspecialchars(substr($a_str, $pos1)));
646  }
647  } else {
648  $encoded = nl2br(htmlspecialchars($a_str));
649  }
650  return $encoded;
651  }
652 
653  private static function maskAttributeTag(string $a_str, string $tag, string $tag_att): string
654  {
655  global $DIC;
656 
657  $ilLog = $DIC["ilLog"];
658 
659  $ws = "[\s]*";
660  $att = $ws . "[^>]*" . $ws;
661 
662  while (preg_match(
663  '/<(' . $tag . $att . '(' . $tag_att . $ws . '="' . $ws . '(([$@!*()~;,_0-9A-z\/:=%.&#?+\-])*)")' . $att . ')>/i',
664  $a_str,
665  $found
666  )) {
667  $old_str = $a_str;
668  $a_str = preg_replace(
669  "/<" . preg_quote($found[1], "/") . ">/i",
670  '&lt;' . $tag . ' ' . $tag_att . $tag_att . '="' . $found[3] . '"&gt;',
671  $a_str
672  );
673  if ($old_str == $a_str) {
674  $ilLog->write(
675  "ilUtil::maskA-" . htmlentities($old_str) . " == " .
676  htmlentities($a_str)
677  );
678  return $a_str;
679  }
680  }
681  $a_str = str_ireplace(
682  "</$tag>",
683  "&lt;/$tag&gt;",
684  $a_str
685  );
686  return $a_str;
687  }
688 
689  private static function unmaskAttributeTag(string $a_str, string $tag, string $tag_att): string
690  {
691  global $DIC;
692 
693  $ilLog = $DIC["ilLog"];
694 
695  while (preg_match(
696  '/&lt;(' . $tag . ' ' . $tag_att . $tag_att . '="(([$@!*()~;,_0-9A-z\/:=%.&#?+\-])*)")&gt;/i',
697  $a_str,
698  $found
699  )) {
700  $old_str = $a_str;
701  $a_str = preg_replace(
702  "/&lt;" . preg_quote($found[1], "/") . "&gt;/i",
703  '<' . $tag . ' ' . $tag_att . '="' . ilUtil::secureLink($found[2]) . '">',
704  $a_str
705  );
706  if ($old_str == $a_str) {
707  $ilLog->write(
708  "ilUtil::unmaskA-" . htmlentities($old_str) . " == " .
709  htmlentities($a_str)
710  );
711  return $a_str;
712  }
713  }
714  $a_str = str_replace('&lt;/' . $tag . '&gt;', '</' . $tag . '>', $a_str);
715  return $a_str;
716  }
717 
718  public static function maskTag(string $a_str, string $tag, array $fix_param = []): string
719  {
720  $a_str = str_replace(
721  ["<$tag>", "<" . strtoupper($tag) . ">"],
722  "&lt;" . $tag . "&gt;",
723  $a_str
724  );
725  $a_str = str_replace(
726  ["</$tag>", "</" . strtoupper($tag) . ">"],
727  "&lt;/" . $tag . "&gt;",
728  $a_str
729  );
730 
731  foreach ($fix_param as $p) {
732  $k = $p["param"];
733  $v = $p["value"];
734  $a_str = str_replace(
735  "<$tag $k=\"$v\">",
736  "&lt;" . "$tag $k=\"$v\"" . "&gt;",
737  $a_str
738  );
739  }
740 
741  return $a_str;
742  }
743 
744  private static function unmaskTag(string $a_str, string $tag, array $fix_param = []): string
745  {
746  $a_str = str_replace("&lt;" . $tag . "&gt;", "<" . $tag . ">", $a_str);
747  $a_str = str_replace("&lt;/" . $tag . "&gt;", "</" . $tag . ">", $a_str);
748 
749  foreach ($fix_param as $p) {
750  $k = $p["param"];
751  $v = $p["value"];
752  $a_str = str_replace(
753  "&lt;$tag $k=\"$v\"&gt;",
754  "<" . "$tag $k=\"$v\"" . ">",
755  $a_str
756  );
757  }
758  return $a_str;
759  }
760 
764  public static function secureLink(string $a_str): string
765  {
766  $a_str = str_ireplace("javascript", "jvscrpt", $a_str);
767  $a_str = str_ireplace(["%00",
768  "%0a",
769  "%0d",
770  "%1a",
771  "&#00;",
772  "&#x00;",
773  "&#0;",
774  "&#x0;",
775  "&#x0a;",
776  "&#x0d;",
777  "&#10;",
778  "&#13;"
779  ], "-", $a_str);
780  return $a_str;
781  }
782 
786  public static function stripScriptHTML(string $a_str, string $a_allow = "", bool $a_rm_js = true): string
787  {
788  $negativestr = "a,abbr,acronym,address,applet,area,base,basefont," .
789  "big,blockquote,body,br,button,caption,center,cite,code,col," .
790  "colgroup,dd,del,dfn,dir,div,dl,dt,em,fieldset,font,form,frame," .
791  "frameset,h1,h2,h3,h4,h5,h6,head,hr,html,i,iframe,img,input,ins,isindex,kbd," .
792  "label,legend,li,link,map,menu,meta,noframes,noscript,object,ol," .
793  "optgroup,option,p,param,q,s,samp,script,select,small,span," .
794  "strike,strong,style,sub,sup,table,tbody,td,textarea,tfoot,th,thead," .
795  "title,tr,tt,u,ul,var";
796  $a_allow = strtolower($a_allow);
797  $negatives = explode(",", $negativestr);
798  $outer_old_str = "";
799  while ($outer_old_str != $a_str) {
800  $outer_old_str = $a_str;
801  foreach ($negatives as $item) {
802  $pos = strpos($a_allow, "<$item>");
803 
804  // remove complete tag, if not allowed
805  if ($pos === false) {
806  $old_str = "";
807  while ($old_str != $a_str) {
808  $old_str = $a_str;
809  $a_str = preg_replace("/<\/?\s*$item(\/?)\s*>/i", "", $a_str);
810  $a_str = preg_replace("/<\/?\s*$item(\/?)\s+([^>]*)>/i", "", $a_str);
811  }
812  }
813  }
814  }
815 
816  if ($a_rm_js) {
817  // remove all attributes if an "on..." attribute is given
818  $a_str = preg_replace("/<\s*\w*(\/?)(\s+[^>]*)?(\s+on[^>]*)>/i", "", $a_str);
819 
820  // remove all attributes if a "javascript" is within tag
821  $a_str = preg_replace("/<\s*\w*(\/?)\s+[^>]*javascript[^>]*>/i", "", $a_str);
822 
823  // remove all attributes if an "expression" is within tag
824  // (IE allows something like <b style='width:expression(alert(1))'>test</b>)
825  $a_str = preg_replace("/<\s*\w*(\/?)\s+[^>]*expression[^>]*>/i", "", $a_str);
826  }
827 
828  return $a_str;
829  }
830 
834  public static function secureUrl(string $url): string
835  {
836  // check if url is valid (absolute or relative)
837  if (filter_var($url, FILTER_VALIDATE_URL) === false &&
838  filter_var("http://" . $url, FILTER_VALIDATE_URL) === false &&
839  filter_var("http:" . $url, FILTER_VALIDATE_URL) === false &&
840  filter_var("http://de.de" . $url, FILTER_VALIDATE_URL) === false &&
841  filter_var("http://de.de/" . $url, FILTER_VALIDATE_URL) === false) {
842  return "";
843  }
844  if (trim(strtolower(parse_url($url, PHP_URL_SCHEME))) == "javascript") {
845  return "";
846  }
847  $url = htmlspecialchars($url, ENT_QUOTES);
848  return $url;
849  }
850 
854  public static function extractParameterString(string $a_parstr): array
855  {
856  // parse parameters in array
857  $par = [];
858  $ok = true;
859  while (($spos = strpos($a_parstr, "=")) && $ok) {
860  // extract parameter
861  $cpar = substr($a_parstr, 0, $spos);
862  $a_parstr = substr($a_parstr, $spos, strlen($a_parstr) - $spos);
863  while (substr($cpar, 0, 1) == "," || substr($cpar, 0, 1) == " " || substr($cpar, 0, 1) == chr(13) || substr(
864  $cpar,
865  0,
866  1
867  ) == chr(10)) {
868  $cpar = substr($cpar, 1, strlen($cpar) - 1);
869  }
870  while (substr($cpar, strlen($cpar) - 1, 1) == " " || substr($cpar, strlen($cpar) - 1, 1) == chr(
871  13
872  ) || substr($cpar, strlen($cpar) - 1, 1) == chr(10)) {
873  $cpar = substr($cpar, 0, strlen($cpar) - 1);
874  }
875 
876  // parameter name should only
877  $cpar_old = "";
878  while ($cpar != $cpar_old) {
879  $cpar_old = $cpar;
880  $cpar = preg_replace("/[^a-zA-Z0-9_]/i", "", $cpar);
881  }
882 
883  // extract value
884  if ($cpar != "") {
885  if ($spos = strpos($a_parstr, "\"")) {
886  $a_parstr = substr($a_parstr, $spos + 1, strlen($a_parstr) - $spos);
887  $spos = strpos($a_parstr, "\"");
888  if (is_int($spos)) {
889  $cval = substr($a_parstr, 0, $spos);
890  $par[$cpar] = $cval;
891  $a_parstr = substr($a_parstr, $spos + 1, strlen($a_parstr) - $spos - 1);
892  } else {
893  $ok = false;
894  }
895  } else {
896  $ok = false;
897  }
898  }
899  }
900 
901  return $ok ? $par : [];
902  }
903 
907  public static function yn2tf(string $a_yn): bool
908  {
909  if (strtolower($a_yn) === "y") {
910  return true;
911  } else {
912  return false;
913  }
914  }
915 
919  public static function tf2yn(bool $a_tf): string
920  {
921  if ($a_tf) {
922  return "y";
923  } else {
924  return "n";
925  }
926  }
927 
933  public static function deducibleSize(string $a_mime): bool
934  {
935  if (($a_mime == "image/gif") || ($a_mime == "image/jpeg") ||
936  ($a_mime == "image/png") || ($a_mime == "application/x-shockwave-flash") ||
937  ($a_mime == "image/tiff") || ($a_mime == "image/x-ms-bmp") ||
938  ($a_mime == "image/psd") || ($a_mime == "image/iff")) {
939  return true;
940  } else {
941  return false;
942  }
943  }
944 
948  public static function redirect(string $a_script): void
949  {
950  global $DIC;
951 
952  if (!isset($DIC['ilCtrl']) || !$DIC['ilCtrl'] instanceof ilCtrl) {
953  (new InitCtrlService())->init($DIC);
954  }
955  $DIC->ctrl()->redirectToURL($a_script);
956  }
957 
965  public static function insertInstIntoID(string $a_value): string
966  {
967  if (substr($a_value, 0, 4) == "il__") {
968  $a_value = "il_" . IL_INST_ID . "_" . substr($a_value, 4, strlen($a_value) - 4);
969  }
970 
971  return $a_value;
972  }
973 
985  public static function groupNameExists(string $a_group_name, ?int $a_id = null): bool
986  {
987  global $DIC;
988 
989  $ilDB = $DIC->database();
990 
991  $ilErr = null;
992  if (isset($DIC["ilErr"])) {
993  $ilErr = $DIC["ilErr"];
994  }
995 
996  if (empty($a_group_name)) {
997  $message = __METHOD__ . ": No groupname given!";
998  $ilErr->raiseError($message, $ilErr->WARNING);
999  }
1000 
1001  $clause = ($a_id !== null) ? " AND obj_id != " . $ilDB->quote($a_id) . " " : "";
1002 
1003  $q = "SELECT obj_id FROM object_data " .
1004  "WHERE title = " . $ilDB->quote($a_group_name, "text") . " " .
1005  "AND type = " . $ilDB->quote("grp", "text") .
1006  $clause;
1007 
1008  $r = $ilDB->query($q);
1009 
1010  return $r->numRows() > 0;
1011  }
1012 
1016  public static function isWindows(): bool
1017  {
1018  return (strtolower(substr(php_uname(), 0, 3)) === "win");
1019  }
1020 
1026  public static function now(): string
1027  {
1028  return date("Y-m-d H:i:s");
1029  }
1030 
1059  public static function _getObjectsByOperations(
1060  $a_obj_type,
1061  string $a_operation,
1062  int $a_usr_id = 0,
1063  int $limit = 0
1064  ): array {
1065  global $DIC;
1066 
1067  $ilDB = $DIC->database();
1068  $rbacreview = $DIC->rbac()->review();
1069  $ilAccess = $DIC->access();
1070  $ilUser = $DIC->user();
1071  $ilSetting = $DIC->settings();
1072  $tree = $DIC->repositoryTree();
1073 
1074  if (!is_array($a_obj_type)) {
1075  $where = "WHERE type = " . $ilDB->quote($a_obj_type, "text") . " ";
1076  } else {
1077  $where = "WHERE " . $ilDB->in("type", $a_obj_type, false, "text") . " ";
1078  }
1079 
1080  // limit number of results default is search result limit
1081  if (!$limit) {
1082  $limit = (int) $ilSetting->get('search_max_hits', "100");
1083  }
1084  if ($limit == -1) {
1085  $limit = 10000;
1086  }
1087 
1088  // default to logged in usr
1089  $a_usr_id = $a_usr_id ?: $ilUser->getId();
1090  $a_roles = $rbacreview->assignedRoles($a_usr_id);
1091 
1092  // Since no rbac_pa entries are available for the system role. This function returns !all! ref_ids in the case the user
1093  // is assigned to the system role
1094  if ($rbacreview->isAssigned($a_usr_id, SYSTEM_ROLE_ID)) {
1095  $query = "SELECT ref_id FROM object_reference obr LEFT JOIN object_data obd ON obr.obj_id = obd.obj_id " .
1096  "LEFT JOIN tree ON obr.ref_id = tree.child " .
1097  $where .
1098  "AND tree = 1";
1099 
1100  $res = $ilDB->query($query);
1101  $counter = 0;
1102  $ref_ids = [];
1103  while ($row = $ilDB->fetchObject($res)) {
1104  // Filter recovery folder
1105  if ($tree->isGrandChild(RECOVERY_FOLDER_ID, $row->ref_id)) {
1106  continue;
1107  }
1108 
1109  if ($counter++ >= $limit) {
1110  break;
1111  }
1112 
1113  $ref_ids[] = $row->ref_id;
1114  }
1115  return $ref_ids;
1116  } // End Administrators
1117 
1118  // Check ownership if it is not asked for edit_permission or a create permission
1119  if ($a_operation == 'edit_permissions' or strpos($a_operation, 'create') !== false) {
1120  $check_owner = ") ";
1121  } else {
1122  $check_owner = "OR owner = " . $ilDB->quote($a_usr_id, "integer") . ") ";
1123  }
1124 
1125  $ops_ids = ilRbacReview::_getOperationIdsByName([$a_operation]);
1126  $ops_id = $ops_ids[0];
1127 
1128  $and = "AND ((" . $ilDB->in("rol_id", $a_roles, false, "integer") . " ";
1129 
1130  $query = "SELECT DISTINCT(obr.ref_id),obr.obj_id,type FROM object_reference obr " .
1131  "JOIN object_data obd ON obd.obj_id = obr.obj_id " .
1132  "LEFT JOIN rbac_pa ON obr.ref_id = rbac_pa.ref_id " .
1133  $where .
1134  $and .
1135  "AND (" . $ilDB->like("ops_id", "text", "%i:" . $ops_id . "%") . " " .
1136  "OR " . $ilDB->like("ops_id", "text", "%:\"" . $ops_id . "\";%") . ")) " .
1137  $check_owner;
1138 
1139  $res = $ilDB->query($query);
1140  $counter = 0;
1141  $ref_ids = [];
1142  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
1143  if ($counter >= $limit) {
1144  break;
1145  }
1146 
1147  // Filter objects in recovery folder
1148  if ($tree->isGrandChild(RECOVERY_FOLDER_ID, $row->ref_id)) {
1149  continue;
1150  }
1151 
1152  // Check deleted, hierarchical access ...
1153  if ($ilAccess->checkAccessOfUser($a_usr_id, $a_operation, '', $row->ref_id, $row->type, $row->obj_id)) {
1154  $counter++;
1155  $ref_ids[] = $row->ref_id;
1156  }
1157  }
1158  return $ref_ids ?: [];
1159  }
1160 
1169  public static function isHTML(string $a_text): bool
1170  {
1171  if (strlen(strip_tags($a_text)) < strlen($a_text)) {
1172  return true;
1173  }
1174 
1175  return false;
1176  }
1177 
1184  public static function __extractRefId(string $role_title): ?int
1185  {
1186  $test_str = explode('_', $role_title);
1187  $prefix = $test_str[0] ?? '';
1188 
1189  if ($prefix === 'il') {
1190  $ref_id = $test_str[3] ?? null;
1191  return is_numeric($ref_id) ? (int) $ref_id : null;
1192  }
1193  return null;
1194  }
1195 
1204  public static function __extractId(string $ilias_id, int $inst_id): ?int
1205  {
1206  $test_str = explode('_', $ilias_id);
1207 
1208  $parsed_inst_id = (int) ($test_str[1] ?? 0);
1209  $prefix = $test_str[0] ?? '';
1210 
1211  if ($prefix === 'il' && $parsed_inst_id === $inst_id && count($test_str) === 4) {
1212  return is_numeric($test_str[3]) ? (int) $test_str[3] : null;
1213  }
1214  return null;
1215  }
1216 
1223  public static function _sortIds(array $a_ids, string $a_table, string $a_field, string $a_id_name): array
1224  {
1225  global $DIC;
1226 
1227  $ilDB = $DIC->database();
1228 
1229  if (!$a_ids) {
1230  return [];
1231  }
1232 
1233  // use database to sort user array
1234  $where = "WHERE " . $a_id_name . " IN (";
1235  $where .= implode(",", ilArrayUtil::quoteArray($a_ids));
1236  $where .= ") ";
1237 
1238  $query = "SELECT " . $a_id_name . " FROM " . $a_table . " " .
1239  $where .
1240  "ORDER BY " . $a_field;
1241 
1242  $res = $ilDB->query($query);
1243  $ids = [];
1244  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
1245  $ids[] = $row->$a_id_name;
1246  }
1247  return $ids;
1248  }
1249 
1257  public static function getSystemMessageHTML(string $a_txt, string $a_type = "info")
1258  {
1259  global $DIC;
1260 
1261  $box_factory = $DIC->ui()->factory()->messageBox();
1262  switch ($a_type) {
1263  case 'info':
1264  $box = $box_factory->info($a_txt);
1265  break;
1266  case 'success':
1267  $box = $box_factory->success($a_txt);
1268  break;
1269  case 'question':
1270  $box = $box_factory->confirmation($a_txt);
1271  break;
1272  case 'failure':
1273  $box = $box_factory->failure($a_txt);
1274  break;
1275  default:
1276  throw new InvalidArgumentException();
1277  }
1278 
1279  return $DIC->ui()->renderer()->render($box);
1280  }
1281 
1285  public static function setCookie(
1286  string $a_cookie_name,
1287  string $a_cookie_value = '',
1288  bool $a_also_set_super_global = true,
1289  bool $a_set_cookie_invalid = false
1290  ): void {
1291  global $DIC;
1292 
1293  $http = $DIC->http();
1294  $cookie_jar = $http->cookieJar();
1295 
1296  $cookie_factory = new CookieFactoryImpl();
1297 
1298  $cookie_expire = null;
1299  if (defined('IL_COOKIE_EXPIRE') && is_numeric(IL_COOKIE_EXPIRE) && IL_COOKIE_EXPIRE > 0) {
1300  $cookie_expire = (int) IL_COOKIE_EXPIRE;
1301  }
1302 
1303  $expires = null;
1304  if ($a_set_cookie_invalid) {
1305  $expires = time() - 10;
1306  } elseif ($cookie_expire > 0) {
1307  $expires = time() + $cookie_expire;
1308  }
1309 
1310  $cookie = $cookie_factory->create($a_cookie_name, $a_cookie_value)
1311  ->withExpires($expires)
1312  ->withSecure(defined('IL_COOKIE_SECURE') ? IL_COOKIE_SECURE : false)
1313  ->withPath(defined('IL_COOKIE_PATH') ? IL_COOKIE_PATH : '')
1314  ->withDomain(defined('IL_COOKIE_DOMAIN') ? IL_COOKIE_DOMAIN : '')
1315  ->withHttpOnly(defined('IL_COOKIE_HTTPONLY') ? IL_COOKIE_HTTPONLY : false);
1316 
1317 
1318  if (
1319  defined('IL_COOKIE_SECURE') && IL_COOKIE_SECURE &&
1320  (!isset(session_get_cookie_params()['samesite']) || strtolower(session_get_cookie_params()['samesite']) !== 'strict')
1321  ) {
1322  $cookie = $cookie->withSamesite(Cookie::SAMESITE_LAX);
1323  }
1324  $jar = $cookie_jar->with($cookie);
1325  $response = $jar->renderIntoResponseHeader($http->response());
1326  $http->saveResponse($response);
1327  }
1328 
1332  public static function _getHttpPath(): string
1333  {
1334  global $DIC;
1335 
1336  $ilIliasIniFile = $DIC["ilIliasIniFile"];
1337 
1338  if ((isset($_SERVER['SHELL']) && $_SERVER['SHELL']) || PHP_SAPI === 'cli' ||
1339  // fallback for windows systems, useful in crons
1340  (class_exists("ilContext") && !ilContext::usesHTTP())) {
1341  return $ilIliasIniFile->readVariable('server', 'http_path');
1342  } else {
1343  return ILIAS_HTTP_PATH;
1344  }
1345  }
1346 
1361  public static function parseImportId(string $a_import_id): array
1362  {
1363  $exploded = explode('_', $a_import_id);
1364 
1365  $parsed['orig'] = $a_import_id;
1366  if ($exploded[0] == 'il') {
1367  $parsed['prefix'] = $exploded[0];
1368  }
1369  if (is_numeric($exploded[1])) {
1370  $parsed['inst_id'] = (int) $exploded[1];
1371  }
1372  $parsed['type'] = $exploded[2];
1373 
1374  if (is_numeric($exploded[3])) {
1375  $parsed['id'] = (int) $exploded[3];
1376  }
1377  return $parsed;
1378  }
1379 
1389  protected static function fmtFloat(
1390  float $a_float,
1391  int $a_decimals = 0,
1392  string $a_dec_point = null,
1393  string $a_thousands_sep = null,
1394  bool $a_suppress_dot_zero = false
1395  ): string {
1396  global $DIC;
1397 
1398  $lng = $DIC->language();
1399 
1400  if ($a_dec_point === null) {
1401  $a_dec_point = ".";
1402  }
1403  if ($a_dec_point === '-lang_sep_decimal-') {
1404  $a_dec_point = ".";
1405  }
1406 
1407  if ($a_thousands_sep === null) {
1408  $a_thousands_sep = $lng->txt('lang_sep_thousand');
1409  }
1410  if ($a_thousands_sep === '-lang_sep_thousand-') {
1411  $a_thousands_sep = ",";
1412  }
1413 
1414  $txt = number_format($a_float, $a_decimals, $a_dec_point, $a_thousands_sep);
1415 
1416  // remove trailing ".0"
1417  if (($a_suppress_dot_zero == 0 || $a_decimals == 0)
1418  && substr($txt, -2) == $a_dec_point . '0'
1419  ) {
1420  $txt = substr($txt, 0, strlen($txt) - 2);
1421  }
1422  if ($a_float == 0 and $txt == "") {
1423  $txt = "0";
1424  }
1425 
1426  return $txt;
1427  }
1428 
1445  public static function formatSize(int $size, string $a_mode = 'short', ?ilLanguage $a_lng = null): string
1446  {
1447  global $DIC;
1448 
1449  $lng = $DIC->language();
1450  if ($a_lng == null) {
1451  $a_lng = $lng;
1452  }
1453 
1454  $mag = 1024;
1455 
1456  if ($size >= $mag * $mag * $mag) {
1457  $scaled_size = $size / $mag / $mag / $mag;
1458  $scaled_unit = 'lang_size_gb';
1459  } else {
1460  if ($size >= $mag * $mag) {
1461  $scaled_size = $size / $mag / $mag;
1462  $scaled_unit = 'lang_size_mb';
1463  } else {
1464  if ($size >= $mag) {
1465  $scaled_size = $size / $mag;
1466  $scaled_unit = 'lang_size_kb';
1467  } else {
1468  $scaled_size = $size;
1469  $scaled_unit = 'lang_size_bytes';
1470  }
1471  }
1472  }
1473 
1474  $result = self::fmtFloat(
1475  $scaled_size,
1476  ($scaled_unit
1477  == 'lang_size_bytes') ? 0 : 1,
1478  $a_lng->txt('lang_sep_decimal'),
1479  $a_lng->txt('lang_sep_thousand'),
1480  true
1481  )
1482  . ' ' . $a_lng->txt($scaled_unit);
1483  if ($a_mode == 'long' && $size > $mag) {
1484  $result .= ' (' . self::fmtFloat(
1485  $size,
1486  0,
1487  $a_lng->txt('lang_sep_decimal'),
1488  $a_lng->txt('lang_sep_thousand')
1489  ) . ' '
1490  . $a_lng->txt('lang_size_bytes') . ')';
1491  }
1492 
1493  return $result;
1494  }
1495 }
setMimeType(string $mime_type)
Definition: Delivery.php:260
$ilIliasIniFile
Definition: imgupload.php:32
$res
Definition: ltiservices.php:69
static appendUrlParameterString(string $a_url, string $a_par, bool $xml_style=false)
static getSystemMessageHTML(string $a_txt, string $a_type="info")
Get HTML for a system message.
const IL_INST_ID
Definition: constants.php:40
static quoteArray(array $a_array)
Quotes all members of an array for usage in DB query statement.
static _getIcon(int $obj_id=0, string $size="big", string $type="", bool $offline=false)
Get icon for repository item.
Class InitCtrlService wraps the initialization of ilCtrl.
static is_email(string $a_email, ilMailRfc822AddressParserFactory $mailAddressParserFactory=null)
This preg-based function checks whether an e-mail address is formally valid.
const ILIAS_HOST
static usesHTTP()
Uses HTTP aka browser.
static isHTML(string $a_text)
Checks if a given string contains HTML or not.
static switchColor(int $a_num, string $a_css1, string $a_css2)
switches style sheets for each even $a_num (used for changing colors of different result rows) ...
$lng
const SYSTEM_ROLE_ID
Definition: constants.php:29
static secureString(string $a_str, bool $a_strip_html=true, string $a_allow="")
static stripSlashes(string $a_str, bool $a_strip_html=true, string $a_allow="")
static getImagePath(string $img, string $module_path="", string $mode="output", bool $offline=false)
get image path (for images located in a template directory)
static stripScriptHTML(string $a_str, string $a_allow="", bool $a_rm_js=true)
static getImageTagByType(string $a_type, string $a_path, bool $a_big=false)
Builds an html image tag.
static maskTag(string $a_str, string $tag, array $fix_param=[])
static maskSecureTags(string $a_str, array $allow_array)
static replaceLinkProperties(array $matches)
static _getOperationIdsByName(array $operations)
get ops_id&#39;s by name.
static getSecureTags()
static tf2yn(bool $a_tf)
static deliverData(string $a_data, string $a_filename, string $mime="application/octet-stream")
static getStyleSheetLocation(string $mode="output", string $a_css_name="", string $a_css_location="")
get full style sheet file name (path inclusive) of current user
static secureLink(string $a_str)
static secureUrl(string $url)
static img(string $a_src, ?string $a_alt=null, $a_width="", $a_height="", $a_border=0, $a_id="", $a_class="")
Build img tag.
static now()
Return current timestamp in Y-m-d H:i:s format.
$ilErr
Definition: raiseError.php:17
static isWindows()
static fmtFloat(float $a_float, int $a_decimals=0, string $a_dec_point=null, string $a_thousands_sep=null, bool $a_suppress_dot_zero=false)
format a float
static getNewContentStyleSheetLocation(string $mode="output")
get full style sheet file name (path inclusive) of current user
static htmlencodePlainString(string $a_str, bool $a_make_links_clickable, bool $a_detect_goto_links=false)
Encodes a plain text string into HTML for display in a browser.
global $DIC
Definition: feed.php:28
Class ilMailRfc822AddressParserFactory.
static unmaskAttributeTag(string $a_str, string $tag, string $tag_att)
$ref_id
Definition: ltiauth.php:67
static securePlainString(string $a_str)
static getCurrentSkin()
get the current skin use always this function instead of getting the account&#39;s skin the current skin ...
static setCookie(string $a_cookie_name, string $a_cookie_value='', bool $a_also_set_super_global=true, bool $a_set_cookie_invalid=false)
$_SERVER['HTTP_HOST']
Definition: raiseError.php:10
static formatSize(int $size, string $a_mode='short', ?ilLanguage $a_lng=null)
Returns the specified file size value in a human friendly form.
static isLogin(string $a_login)
static unmaskSecureTags(string $a_str, array $allow_array)
$query
static getHtmlPath(string $relative_path)
get url of path
static _getObjectsByOperations( $a_obj_type, string $a_operation, int $a_usr_id=0, int $limit=0)
Get all objects of a specific type and check access This function is not recursive, instead it parses the serialized rbac_pa entries.
$http
Definition: raiseError.php:7
$txt
Definition: error.php:13
static parseImportId(string $a_import_id)
Parse an ilias import id Typically of type il_[IL_INST_ID]_[OBJ_TYPE]_[OBJ_ID] returns array( &#39;orig&#39; ...
$filename
Definition: buildRTE.php:78
$img
Definition: imgupload.php:83
static _sortIds(array $a_ids, string $a_table, string $a_field, string $a_id_name)
Function that sorts ids by a given table field using WHERE IN E.g: __sort(array(6,7),&#39;usr_data&#39;,&#39;lastname&#39;,&#39;usr_id&#39;) => sorts by lastname.
static redirect(string $a_script)
static maskAttributeTag(string $a_str, string $tag, string $tag_att)
Class Delivery.
Definition: Delivery.php:37
static deducibleSize(string $a_mime)
checks if mime type is provided by getimagesize()
static _getHttpPath()
static extractParameterString(string $a_parstr)
global $ilSetting
Definition: privfeed.php:17
static __extractId(string $ilias_id, int $inst_id)
extract ref id from role title, e.g.
$ilUser
Definition: imgupload.php:34
const RECOVERY_FOLDER_ID
Definition: constants.php:37
static groupNameExists(string $a_group_name, ?int $a_id=null)
checks if group name already exists.
const IL_COOKIE_PATH(isset($_GET["client_id"]))
Definition: metadata.php:64
$message
Definition: xapiexit.php:32
static yn2tf(string $a_yn)
$url
static getCurrentStyle()
get the current style or sub style use always this function instead of getting the account&#39;s style th...
static unmaskTag(string $a_str, string $tag, array $fix_param=[])
static insertInstIntoID(string $a_value)
inserts installation id into ILIAS id
$response
static makeClickable(string $a_text, bool $detectGotoLinks=false)
static __extractRefId(string $role_title)
extract ref id from role title, e.g.
static stripOnlySlashes(string $a_str)