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