ILIAS  Release_4_4_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.ilUtil.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (c) 1998-2010 ILIAS open source, Extended GPL, see docs/LICENSE */
3 
17 class ilUtil
18 {
29  public static function getImageTagByType($a_type, $a_path, $a_big = false)
30  {
31  global $lng;
32 
33  if ($a_big)
34  {
35  $big = "_b";
36  }
37  $filename = "icon_".$a_type."$big.png";
38 
39  return "<img src=\"".ilUtil::getImagePath($filename)."\" alt=\"".$lng->txt("obj_".$a_type)."\" title=\"".$lng->txt("obj_".$a_type)."\" border=\"0\" vspace=\"0\"/>";
40  //return "<img src=\"".$a_path."/images/"."icon_".$a_type."$big.png\" alt=\"".$lng->txt("obj_".$a_type)."\" title=\"".$lng->txt("obj_".$a_type)."\" border=\"0\" vspace=\"0\"/>";
41  }
42 
55  public static function getTypeIconPath($a_type,$a_obj_id,$a_size = 'small')
56  {
57  global $ilSetting, $objDefinition;
58 
59  if($ilSetting->get("custom_icons"))
60  {
61  switch($a_type)
62  {
63  case 'cat':
64  case 'crs':
65  case 'grp':
66  include_once('./Services/Container/classes/class.ilContainer.php');
67  if(strlen($path = ilContainer::_lookupIconPath($a_obj_id,$a_size)))
68  {
69  return $path;
70  }
71  }
72  }
73 
74  if ($objDefinition->isPluginTypeName($a_type))
75  {
76  $class_name = "il".$objDefinition->getClassName($a_type).'Plugin';
77  $location = $objDefinition->getLocation($a_type);
78  include_once($location."/class.".$class_name.".php");
79  return call_user_func(array($class_name, "_getIcon"), $a_type, $a_size, $a_obj_id);
80  }
81 
82  switch($a_size)
83  {
84  case 'tiny':
85  $postfix = '_s.png';
86  break;
87  case 'big':
88  $postfix = '_b.png';
89  break;
90  default:
91  $postfix = '.png';
92  break;
93  }
94  return ilUtil::getImagePath('icon_'.$a_type.$postfix);
95  }
96 
107  public static function getImagePath($img, $module_path = "", $mode = "output", $offline = false)
108  {
109  global $ilias, $styleDefinition, $ilCtrl, $ilUser;
110 
111  if (is_int(strpos($_SERVER["PHP_SELF"], "setup.php")))
112  {
113  $module_path = "..";
114  }
115  if ($module_path != "")
116  {
117  $module_path = "/".$module_path;
118  }
119 
120  // default image
121  $default_img = ".".$module_path."/templates/default/images/".$img;
122 
123  // use ilStyleDefinition instead of account to get the current skin and style
124  require_once("./Services/Style/classes/class.ilStyleDefinition.php");
125  $current_skin = ilStyleDefinition::getCurrentSkin();
126  $current_style = ilStyleDefinition::getCurrentStyle();
127 
128  if (is_object($styleDefinition))
129  {
130  $image_dir = $styleDefinition->getImageDirectory(
132  $current_style);
133  }
134  if ($current_skin == "default")
135  {
136  $user_img = ".".$module_path."/templates/default/".$image_dir."/".$img;
137  $skin_img = ".".$module_path."/templates/default/images/".$img;
138  }
139  else if (is_object($styleDefinition) && $current_skin != "default")
140  {
141  $user_img = "./Customizing/global/skin/".
142  $current_skin.$module_path."/".$image_dir."/".$img;
143  $skin_img = "./Customizing/global/skin/".
144  $current_skin.$module_path."/images/".$img;
145  }
146 
147  if ($offline)
148  {
149  return "./images/".$img;
150  }
151  else if (@file_exists($user_img) && $image_dir != "")
152  {
153  return $user_img; // found image for skin and style
154  }
155  else if (file_exists($skin_img))
156  {
157  return $skin_img; // found image in skin/images
158  }
159 
160  return $default_img; // take image in default
161  }
162 
173  public static function getHtmlPath($relative_path)
174  {
175  if (substr($relative_path, 0, 2) == './')
176  {
177  $relative_path = (substr($relative_path, 1));
178  }
179  if (substr($relative_path, 0, 1) != '/')
180  {
181  $relative_path = '/' . $relative_path;
182  }
183  $htmlpath = ILIAS_HTTP_PATH . $relative_path;
184  return $htmlpath;
185  }
186 
199  public static function getStyleSheetLocation($mode = "output", $a_css_name = "", $a_css_location = "")
200  {
201  global $ilias;
202 
203  // add version as parameter to force reload for new releases
204  // use ilStyleDefinition instead of account to get the current style
205  require_once("./Services/Style/classes/class.ilStyleDefinition.php");
206  $stylesheet_name = (strlen($a_css_name))
207  ? $a_css_name
209  if (strlen($a_css_location) && (strcmp(substr($a_css_location, -1), "/") != 0))
210  {
211  $a_css_location = $a_css_location . "/";
212  }
213 
214  $filename = "";
215  // use ilStyleDefinition instead of account to get the current skin
216  require_once("./Services/Style/classes/class.ilStyleDefinition.php");
217  if (ilStyleDefinition::getCurrentSkin() != "default")
218  {
219  $filename = "./Customizing/global/skin/".ilStyleDefinition::getCurrentSkin()."/".$a_css_location.$stylesheet_name;
220  }
221  if (strlen($filename) == 0 || !file_exists($filename))
222  {
223  $filename = "./" . $a_css_location . "templates/default/".$stylesheet_name;
224  }
225  $vers = "";
226  if ($mode != "filesystem")
227  {
228  $vers = str_replace(" ", "-", $ilias->getSetting("ilias_version"));
229  $vers = "?vers=".str_replace(".", "-", $vers);
230  }
231  return $filename . $vers;
232  }
233 
244  public static function getJSLocation($a_js_name, $a_js_location = "", $add_version = FALSE)
245  {
246  global $ilias;
247 
248  // add version as parameter to force reload for new releases
249  $js_name = $a_js_name;
250  if (strlen($a_js_location) && (strcmp(substr($a_js_location, -1), "/") != 0)) $a_js_location = $a_js_location . "/";
251 
252  $filename = "";
253  // use ilStyleDefinition instead of account to get the current skin
254  require_once("./Services/Style/classes/class.ilStyleDefinition.php");
255  if (ilStyleDefinition::getCurrentSkin() != "default")
256  {
257  $filename = "./Customizing/global/skin/".ilStyleDefinition::getCurrentSkin()."/".$a_js_location.$js_name;
258  }
259  if (strlen($filename) == 0 || !file_exists($filename))
260  {
261  $filename = "./" . $a_js_location . "templates/default/".$js_name;
262  }
263  $vers = "";
264  if ($add_version)
265  {
266  $vers = str_replace(" ", "-", $ilias->getSetting("ilias_version"));
267  $vers = "?vers=".str_replace(".", "-", $vers);
268  }
269  return $filename . $vers;
270  }
271 
279  public static function getP3PLocation()
280  {
281  global $ilias;
282 
283  if (defined("ILIAS_MODULE"))
284  {
285  $base = '';
286  for($i = 0;$i < count(explode('/',ILIAS_MODULE));$i++)
287  {
288  $base .= "../Services/Privacy/";
289  }
290  }
291  else
292  {
293  $base = "./Services/Privacy/";
294  }
295 
296  if (is_file($base."w3c/p3p.xml"))
297  {
298  return ILIAS_HTTP_PATH."w3c/p3p.xml";
299  }
300  else
301  {
302  return ILIAS_HTTP_PATH."/w3c/p3p_template.xml";
303  }
304  }
305 
313  public static function getNewContentStyleSheetLocation($mode = "output")
314  {
315  global $ilias;
316 
317  // add version as parameter to force reload for new releases
318  if ($mode != "filesystem")
319  {
320  $vers = str_replace(" ", "-", $ilias->getSetting("ilias_version"));
321  $vers = "?vers=".str_replace(".", "-", $vers);
322  }
323 
324  // use ilStyleDefinition instead of account to get the current skin and style
325  require_once("./Services/Style/classes/class.ilStyleDefinition.php");
326  if (ilStyleDefinition::getCurrentSkin() == "default")
327  {
328  $in_style = "./templates/".ilStyleDefinition::getCurrentSkin()."/"
329  .ilStyleDefinition::getCurrentStyle()."_cont.css";
330  }
331  else
332  {
333  $in_style = "./Customizing/global/skin/".ilStyleDefinition::getCurrentSkin()."/"
334  .ilStyleDefinition::getCurrentStyle()."_cont.css";
335  }
336 
337  if (is_file("./".$in_style))
338  {
339  return $in_style.$vers;
340  }
341  else
342  {
343  return "templates/default/delos_cont.css".$vers;
344  }
345  }
346 
365  public static function formSelect($selected,$varname,$options,$multiple = false,$direct_text = false, $size = "0",
366  $style_class = "", $attribs = "",$disabled = false)
367  {
368  global $lng;
369 
370  if ($multiple == true)
371  {
372  $multiple = " multiple=\"multiple\"";
373  }
374  else
375  {
376  $multiple = "";
377  $size = 0;
378  }
379 
380  if ($style_class != "")
381  {
382  $class = " class=\"".$style_class."\"";
383  }
384  else
385  {
386  $class = "";
387  }
388  $attributes = "";
389  if (is_array($attribs))
390  {
391  foreach ($attribs as $key => $val)
392  {
393  $attributes .= " ".$key."=\"".$val."\"";
394  }
395  }
396  if($disabled)
397  {
398  $disabled = ' disabled=\"disabled\"';
399  }
400 
401  $str = "<select name=\"".$varname ."\"".$multiple." $class size=\"".$size."\" $attributes $disabled>\n";
402 
403  foreach ((array) $options as $key => $val)
404  {
405  $style = "";
406  if (is_array($val))
407  {
408  $style = $val["style"];
409  $val = $val["text"]; // mus be last line, since we overwrite
410  }
411 
412  $sty = ($style != "")
413  ? ' style="'.$style.'" '
414  : "";
415 
416  if ($direct_text)
417  {
418  $str .= " <option $sty value=\"".$key."\"";
419  }
420  else
421  {
422  $str .= " <option $sty value=\"".$val."\"";
423  }
424  if (is_array($selected) )
425  {
426  if (in_array($key,$selected))
427  {
428  $str .= " selected=\"selected\"";
429  }
430  }
431  else if ($selected == $key)
432  {
433  $str .= " selected=\"selected\"";
434  }
435 
436  if ($direct_text)
437  {
438  $str .= ">".$val."</option>\n";
439  }
440  else
441  {
442  $str .= ">".$lng->txt($val)."</option>\n";
443  }
444  }
445 
446  $str .= "</select>\n";
447 
448  return $str;
449  }
450 
460  public static function getSelectName ($selected,$values)
461  {
462  return($values[$selected]);
463  }
464 
476  public static function formCheckbox ($checked,$varname,$value,$disabled = false)
477  {
478  $str = "<input type=\"checkbox\" name=\"".$varname."\"";
479 
480  if ($checked == 1)
481  {
482  $str .= " checked=\"checked\"";
483  }
484 
485  if ($disabled)
486  {
487  $str .= " disabled=\"disabled\"";
488  }
489 
490  $array_var = false;
491 
492  if (substr($varname,-2) == "[]")
493  {
494  $array_var = true;
495  }
496 
497  // if varname ends with [], use varname[-2] + _ + value as id tag (e.g. "user_id[]" => "user_id_15")
498  if ($array_var)
499  {
500  $varname_id = substr($varname,0,-2)."_".$value;
501  }
502  else
503  {
504  $varname_id = $varname;
505  }
506 
507  // dirty removal of other "[]" in string
508  $varname_id = ereg_replace("\[","_",$varname_id);
509  $varname_id = ereg_replace("\]","",$varname_id);
510 
511  $str .= " value=\"".$value."\" id=\"".$varname_id."\" />\n";
512 
513  return $str;
514  }
515 
527  public static function formDisabledRadioButton($checked,$varname,$value,$disabled)
528  {
529  if ($disabled) {
530  $str = "<input disabled type=\"radio\" name=\"".$varname."\"";
531  }
532  else {
533  $str = "<input type=\"radio\" name=\"".$varname."\"";
534  }
535  if ($checked == 1)
536  {
537  $str .= " checked=\"checked\"";
538  }
539 
540  $str .= " value=\"".$value."\"";
541  $str .= " id=\"".$value."\" />\n";
542 
543  return $str;
544 
545  }
546 
547 
558  public static function formRadioButton($checked,$varname,$value,$onclick=null, $disabled = false)
559  {
560  $str = '<input ';
561 
562  if($onclick)
563  {
564  $str .= ('onclick="'.$onclick.'"');
565  }
566 
567  $str .= (" type=\"radio\" name=\"".$varname."\"");
568  if ($checked == 1)
569  {
570  $str .= " checked=\"checked\"";
571  }
572 
573  if ($disabled)
574  {
575  $str .= " disabled=\"disabled\"";
576  }
577 
578  $str .= " value=\"".$value."\"";
579 
580  $str .= " id=\"".$value."\" />\n";
581 
582  return $str;
583  }
584 
585 
595  public static function formInput($varname,$value,$disabled = false)
596  {
597 
598  $str = "<input type=\"input\" name=\"".$varname."\"";
599  if ($disabled)
600  {
601  $str .= " disabled";
602  }
603 
604  $str .= " value=\"".$value."\"";
605 
606  $str .= " id=\"".$value."\" />\n";
607 
608  return $str;
609  }
610 
611 
618  public static function checkInput ($vars)
619  {
620  // TO DO:
621  // Diese Funktion soll Formfeldeingaben berprfen (empty und required)
622  }
623 
630  public static function setPathStr ($a_path)
631  {
632  if ("" != $a_path && "/" != substr($a_path, -1))
633  {
634  $a_path .= "/";
635  //$a_path = substr($a_path,1);
636  }
637 
638  //return getcwd().$a_path;
639  return $a_path;
640  }
641 
654  public static function switchColor ($a_num,$a_css1,$a_css2)
655  {
656  if (!($a_num % 2))
657  {
658  return $a_css1;
659  }
660  else
661  {
662  return $a_css2;
663  }
664  }
665 
674  public static function checkFormEmpty ($emptyFields)
675  {
676 
677  $feedback = "";
678 
679  foreach ($emptyFields as $key => $val)
680  {
681  if ($val == "") {
682  if ($feedback != "") $feedback .= ", ";
683  $feedback .= $key;
684  }
685  }
686 
687  return $feedback;
688  }
689 
714  public static function Linkbar ($AScript,$AHits,$ALimit,$AOffset,$AParams = array(),$ALayout = array(), $prefix = '')
715  {
716  $LinkBar = "";
717 
718  $layout_link = "";
719  $layout_prev = "&lt;&lt;";
720  $layout_next = "&gt;&gt;";
721 
722  // layout options
723  if (count($ALayout > 0))
724  {
725  if ($ALayout["link"])
726  {
727  $layout_link = " class=\"".$ALayout["link"]."\"";
728  }
729 
730  if ($ALayout["prev"])
731  {
732  $layout_prev = $ALayout["prev"];
733  }
734 
735  if ($ALayout["next"])
736  {
737  $layout_next = $ALayout["next"];
738  }
739  }
740 
741  // show links, if hits greater limit
742  // or offset > 0 (can be > 0 due to former setting)
743  if ($AHits > $ALimit || $AOffset > 0)
744  {
745  if (!empty($AParams))
746  {
747  foreach ($AParams as $key => $value)
748  {
749  $params.= $key."=".$value."&";
750  }
751  }
752  // if ($params) $params = substr($params,0,-1);
753  if(strpos($AScript,'&'))
754  {
755  $link = $AScript."&".$params.$prefix."offset=";
756  }
757  else
758  {
759  $link = $AScript."?".$params.$prefix."offset=";
760  }
761 
762  // ?bergehe "zurck"-link, wenn offset 0 ist.
763  if ($AOffset >= 1)
764  {
765  $prevoffset = $AOffset - $ALimit;
766  if ($prevoffset < 0) $prevoffset = 0;
767  $LinkBar .= "<a".$layout_link." href=\"".$link.$prevoffset."\">".$layout_prev."&nbsp;</a>";
768  }
769 
770  // Ben?tigte Seitenzahl kalkulieren
771  $pages=intval($AHits/$ALimit);
772 
773  // Wenn ein Rest bleibt, addiere eine Seite
774  if (($AHits % $ALimit))
775  $pages++;
776 
777  // Bei Offset = 0 keine Seitenzahlen anzeigen : DEAKTIVIERT
778  // if ($AOffset != 0) {
779 
780  // ansonsten zeige Links zu den anderen Seiten an
781  for ($i = 1 ;$i <= $pages ; $i++)
782  {
783  $newoffset=$ALimit*($i-1);
784 
785  if ($newoffset == $AOffset)
786  {
787  $LinkBar .= "[".$i."] ";
788  }
789  else
790  {
791  $LinkBar .= '<a '.$layout_link.' href="'.
792  $link.$newoffset.'">['.$i.']</a> ';
793  }
794  }
795  // }
796 
797  // Checken, ob letze Seite erreicht ist
798  // Wenn nicht, gebe einen "Weiter"-Link aus
799  if (! ( ($AOffset/$ALimit)==($pages-1) ) && ($pages!=1) )
800  {
801  $newoffset=$AOffset+$ALimit;
802  $LinkBar .= "<a".$layout_link." href=\"".$link.$newoffset."\">&nbsp;".$layout_next."</a>";
803  }
804 
805  return $LinkBar;
806  }
807  else
808  {
809  return false;
810  }
811  }
812 
824  public static function makeClickable($a_text, $detectGotoLinks = false)
825  {
826  // New code, uses MediaWiki Sanitizer
827  $ret = $a_text;
828 
829  // www-URL ohne ://-Angabe
830  $ret = eregi_replace("(^|[[:space:]]+)(www\.)([[:alnum:]#?/&=\.-]+)",
831  "\\1http://\\2\\3", $ret);
832 
833  // ftp-URL ohne ://-Angabe
834  $ret = eregi_replace("(^|[[:space:]]+)(ftp\.)([[:alnum:]#?/&=\.-]+)",
835  "\\1ftp://\\2\\3", $ret);
836 
837  // E-Mail (this does not work as expected, users must add mailto: manually)
838  //$ret = eregi_replace("(([a-z0-9_]|\\-|\\.)+@([^[:space:]]*)([[:alnum:]-]))",
839  // "mailto:\\1", $ret);
840 
841  // mask existing image tags
842  $ret = str_replace('src="http://', '"***masked_im_start***', $ret);
843 
844  include_once("./Services/Utilities/classes/class.ilMWParserAdapter.php");
845  $parser = new ilMWParserAdapter();
846  $ret = $parser->replaceFreeExternalLinks($ret);
847 
848  // unmask existing image tags
849  $ret = str_replace('"***masked_im_start***', 'src="http://', $ret);
850 
851  // Should be Safe
852 
853  if ($detectGotoLinks)
854  // replace target blank with self and text with object title.
855  {
856  $regExp = "<a[^>]*href=\"(".str_replace("/","\/",ILIAS_HTTP_PATH)."\/goto.php\?target=\w+_(\d+)[^\"]*)\"[^>]*>[^<]*<\/a>";
857 // echo htmlentities($regExp);
858  $ret = preg_replace_callback(
859  "/".$regExp."/i",
860  array("ilUtil", "replaceLinkProperties"),
861  $ret);
862 
863  // Static links
864  $regExp = "<a[^>]*href=\"(".str_replace("/","\/",ILIAS_HTTP_PATH)."\/goto_.*[a-z0-9]+_([0-9]+)\.html)\"[^>]*>[^<]*<\/a>";
865 // echo htmlentities($regExp);
866  $ret = preg_replace_callback(
867  "/".$regExp."/i",
868  array("ilUtil", "replaceLinkProperties"),
869  $ret);
870  }
871 
872  return($ret);
873  }
874 
888  public static function replaceLinkProperties ($matches)
889  {
890  $link = $matches[0];
891  $ref_id = $matches[2];
892 
893  if ($ref_id > 0)
894  {
895  $obj_id = ilObject::_lookupObjId($ref_id);
896  if ($obj_id > 0)
897  {
898  $title = ilObject::_lookupTitle($obj_id);
899  $link = "<a href=".$matches[1]." target=\"_self\">".$title."</a>";
900  }
901  }
902  return $link;
903  }
904 
923  public static function makeDateSelect($prefix, $year = "", $month = "", $day = "", $startyear = "",$a_long_month = true,$a_further_options = array(), $emptyoption = false)
924  {
925  global $lng;
926 
927  $disabled = '';
928  if(isset($a_further_options['disabled']) and $a_further_options['disabled'])
929  {
930  $disabled = 'disabled="disabled" ';
931  }
932 
933  $now = getdate();
934  if (!$emptyoption)
935  {
936  if (!strlen($year)) $year = $now["year"];
937  if (!strlen($month)) $month = $now["mon"];
938  if (!strlen($day)) $day = $now["mday"];
939  }
940 
941  $year = (int) $year;
942  $month = (int) $month;
943  $day = (int) $day;
944 
945  // build day select
946 
947  $sel_day .= '<select ';
948  if(isset($a_further_options['select_attributes']))
949  {
950  foreach($a_further_options['select_attributes'] as $name => $value)
951  {
952  $sel_day .= ($name.'="'.$value.'" ');
953  }
954  }
955 
956  $sel_day .= $disabled."name=\"".$prefix."[d]\" id=\"".$prefix."_d\">\n";
957 
958  if ($emptyoption) $sel_day .= "<option value=\"0\">--</option>\n";
959  for ($i = 1; $i <= 31; $i++)
960  {
961  $sel_day .= "<option value=\"$i\">" . sprintf("%02d", $i) . "</option>\n";
962  }
963  $sel_day .= "</select>\n";
964  $sel_day = preg_replace("/(value\=\"$day\")/", "$1 selected=\"selected\"", $sel_day);
965 
966  // build month select
967  $sel_month = '<select ';
968  if(isset($a_further_options['select_attributes']))
969  {
970  foreach($a_further_options['select_attributes'] as $name => $value)
971  {
972  $sel_month .= ($name.'="'.$value.'" ');
973  }
974  }
975  $sel_month .= $disabled."name=\"".$prefix."[m]\" id=\"".$prefix."_m\">\n";
976 
977  if ($emptyoption) $sel_month .= "<option value=\"0\">--</option>\n";
978  for ($i = 1; $i <= 12; $i++)
979  {
980  if($a_long_month)
981  {
982  $sel_month .= "<option value=\"$i\">" . $lng->txt("month_" . sprintf("%02d", $i) . "_long") . "</option>\n";
983  }
984  else
985  {
986  $sel_month .= "<option value=\"$i\">" . $i . "</option>\n";
987  }
988  }
989  $sel_month .= "</select>\n";
990  $sel_month = preg_replace("/(value\=\"$month\")/", "$1 selected=\"selected\"", $sel_month);
991 
992  // build year select
993  $sel_year = '<select ';
994  if(isset($a_further_options['select_attributes']))
995  {
996  foreach($a_further_options['select_attributes'] as $name => $value)
997  {
998  $sel_year .= ($name.'="'.$value.'" ');
999  }
1000  }
1001  $sel_year .= $disabled."name=\"".$prefix."[y]\" id=\"".$prefix."_y\">\n";
1002  if ((strlen($startyear) == 0) || ($startyear > $year))
1003  {
1004  if (!$emptyoption || $year != 0) $startyear = $year - 5;
1005  }
1006 
1007  if(($year + 5) < (date('Y',time()) + 5))
1008  {
1009  $end_year = date('Y',time()) + 5;
1010  }
1011  else
1012  {
1013  $end_year = $year + 5;
1014  }
1015 
1016  if ($emptyoption) $sel_year .= "<option value=\"0\">----</option>\n";
1017  for ($i = $startyear; $i <= $end_year; $i++)
1018  {
1019  $sel_year .= "<option value=\"$i\">" . sprintf("%04d", $i) . "</option>\n";
1020  }
1021  $sel_year .= "</select>\n";
1022  $sel_year = preg_replace("/(value\=\"$year\")/", "$1 selected=\"selected\"", $sel_year);
1023 
1024  //$dateformat = $lng->text["lang_dateformat"];
1025  $dateformat = "d-m-Y";
1026  $dateformat = strtolower(preg_replace("/\W/", "", $dateformat));
1027  $dateformat = strtolower(preg_replace("/(\w)/", "%%$1", $dateformat));
1028  $dateformat = preg_replace("/%%d/", $sel_day, $dateformat);
1029  $dateformat = preg_replace("/%%m/", $sel_month, $dateformat);
1030  $dateformat = preg_replace("/%%y/", $sel_year, $dateformat);
1031  return $dateformat;
1032  }
1033 
1052  public static function makeTimeSelect($prefix, $short = true, $hour = "", $minute = "", $second = "",$a_use_default = true,$a_further_options = array())
1053  {
1054  global $lng, $ilUser;
1055 
1056  $minute_steps = 1;
1057  $disabled = '';
1058  if(count($a_further_options))
1059  {
1060  if(isset($a_further_options['minute_steps']))
1061  {
1062  $minute_steps = $a_further_options['minute_steps'];
1063  }
1064  if(isset($a_further_options['disabled']) and $a_further_options['disabled'])
1065  {
1066  $disabled = 'disabled="disabled" ';
1067  }
1068  }
1069 
1070  if ($a_use_default and !strlen("$hour$minute$second")) {
1071  $now = localtime();
1072  $hour = $now[2];
1073  $minute = $now[1];
1074  $second = $now[0];
1075  } else {
1076  $hour = (int)$hour;
1077  $minute = (int)$minute;
1078  $second = (int)$second;
1079  }
1080  // build hour select
1081  $sel_hour = '<select ';
1082  if(isset($a_further_options['select_attributes']))
1083  {
1084  foreach($a_further_options['select_attributes'] as $name => $value)
1085  {
1086  $sel_hour .= $name.'='.$value.' ';
1087  }
1088  }
1089  $sel_hour .= " ".$disabled."name=\"".$prefix."[h]\" id=\"".$prefix."_h\">\n";
1090 
1091  $format = $ilUser->getTimeFormat();
1092  for ($i = 0; $i <= 23; $i++)
1093  {
1094  if($format == ilCalendarSettings::TIME_FORMAT_24)
1095  {
1096  $sel_hour .= "<option value=\"$i\">" . sprintf("%02d", $i) . "</option>\n";
1097  }
1098  else
1099  {
1100  $sel_hour .= "<option value=\"$i\">" . date("ga", mktime($i, 0, 0)) . "</option>\n";
1101  }
1102  }
1103  $sel_hour .= "</select>\n";
1104  $sel_hour = preg_replace("/(value\=\"$hour\")/", "$1 selected=\"selected\"", $sel_hour);
1105 
1106  // build minutes select
1107  $sel_minute .= "<select ".$disabled."name=\"".$prefix."[m]\" id=\"".$prefix."_m\">\n";
1108 
1109  for ($i = 0; $i <= 59; $i = $i + $minute_steps)
1110  {
1111  $sel_minute .= "<option value=\"$i\">" . sprintf("%02d", $i) . "</option>\n";
1112  }
1113  $sel_minute .= "</select>\n";
1114  $sel_minute = preg_replace("/(value\=\"$minute\")/", "$1 selected=\"selected\"", $sel_minute);
1115 
1116  if (!$short) {
1117  // build seconds select
1118  $sel_second .= "<select ".$disabled."name=\"".$prefix."[s]\" id=\"".$prefix."_s\">\n";
1119 
1120  for ($i = 0; $i <= 59; $i++)
1121  {
1122  $sel_second .= "<option value=\"$i\">" . sprintf("%02d", $i) . "</option>\n";
1123  }
1124  $sel_second .= "</select>\n";
1125  $sel_second = preg_replace("/(value\=\"$second\")/", "$1 selected=\"selected\"", $sel_second);
1126  }
1127  $timeformat = $lng->text["lang_timeformat"];
1128  if (strlen($timeformat) == 0) $timeformat = "H:i:s";
1129  $timeformat = strtolower(preg_replace("/\W/", "", $timeformat));
1130  $timeformat = preg_replace("/(\w)/", "%%$1", $timeformat);
1131  $timeformat = preg_replace("/%%h/", $sel_hour, $timeformat);
1132  $timeformat = preg_replace("/%%i/", $sel_minute, $timeformat);
1133  if ($short) {
1134  $timeformat = preg_replace("/%%s/", "", $timeformat);
1135  } else {
1136  $timeformat = preg_replace("/%%s/", $sel_second, $timeformat);
1137  }
1138  return $timeformat;
1139  }
1140 
1154  public static function is_email($a_email)
1155  {
1156  // BEGIN Mail: If possible, use PearMail to validate e-mail address
1157  global $ilErr, $ilias;
1158 
1159  // additional check for ilias object is needed,
1160  // otherwise setup will fail with this if branch
1161  if(is_object($ilias))
1162  {
1163  require_once './Services/PEAR/lib/Mail/RFC822.php';
1164  $parser = new Mail_RFC822();
1166  try
1167  {
1168  $addresses = $parser->parseAddressList($a_email, 'ilias', false, true);
1169  if(!is_a($addresses, 'PEAR_Error') &&
1170  count($addresses) == 1 && $addresses[0]->host != 'ilias'
1171  )
1172  {
1173  PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($ilErr, "errorHandler"));
1174  return true;
1175  }
1176  }
1177  catch(Exception $e)
1178  {
1179  PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($ilErr, "errorHandler"));
1180  return false;
1181  }
1182  PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($ilErr, "errorHandler"));
1183  return false;
1184  }
1185  else
1186  {
1187  $tlds = strtolower(
1188  "AC|AD|AE|AERO|AF|AG|AI|AL|AM|AN|AO|AQ|AR|ARPA|AS|ASIA|AT|AU|AW|AX|AZ|BA|BB|BD|BE|BF|BG|BH|BI|BIZ|BJ|BM|BN|BO|BR|BS|BT|BV|BW|BY|".
1189  "BZ|CA|CAT|CC|CD|CF|CG|CH|CI|CK|CL|CM|CN|CO|COM|COOP|CR|CU|CV|CX|CY|CZ|DE|DJ|DK|DM|DO|DZ|EC|EDU|EE|EG|".
1190  "ER|ES|ET|EU|FI|FJ|FK|FM|FO|FR|GA|GB|GD|GE|GF|GG|GH|GI|GL|GM|GN|GOV|GP|GQ|GR|GS|GT|GU|GW|GY|HK|HM|HN|HR|HT|".
1191  "HU|ID|IE|IL|IM|IN|INFO|INT|IO|IQ|IR|IS|IT|JE|JM|JO|JOBS|JP|KE|KG|KH|KI|KM|KN|KP|KR|KW|KY|KZ|LA|LB|LC|".
1192  "LI|LK|LR|LS|LT|LU|LV|LY|MA|MC|MD|ME|MG|MH|MIL|MK|ML|MM|MN|MO|MOBI|MP|MQ|MR|MS|MT|MU|MUSEUM|MV|MW|MX|".
1193  "MY|MZ|NA|NAME|NC|NE|NET|NF|NG|NI|NL|NO|NP|NR|NU|NZ|OM|ORG|PA|PE|PF|PG|PH|PK|PL|PM|PN|PR|PRO|PS|".
1194  "PT|PW|PY|QA|RE|RO|RS|RU|RW|SA|SB|SC|SD|SE|SG|SH|SI|SJ|SK|SL|SM|SN|SO|SR|ST|SU|SV|SY|SZ|TC|TD|TEL|".
1195  "TF|TG|TH|TJ|TK|TL|TM|TN|TO|TP|TR|TRAVEL|TT|TV|TW|TZ|UA|UG|UK|US|UY|UZ|VA|VC|VE|VG|VI|VN|VU|".
1196  "WF|WS|XN|YE|YT|YU|ZA|ZM|ZW");
1197 
1198  return(preg_match("/^[-_.[:alnum:]]+@((([[:alnum:]]|[[:alnum:]][[:alnum:]-]*[[:alnum:]])\.)+(".$tlds.")|(([0-9][0-9]?|[0-1][0-9][0-9]|[2][0-4][0-9]|[2][5][0-5])\.){3}([0-9][0-9]?|[0-1][0-9][0-9]|[2][0-4][0-9]|[2][5][0-5]))$/i",$a_email));
1199  }
1200  // END Mail: If possible, use PearMail to validate e-mail address
1201  }
1202 
1211  public static function isPassword($a_passwd, &$customError = null)
1212  {
1213  global $lng;
1214 
1215  include_once('./Services/PrivacySecurity/classes/class.ilSecuritySettings.php');
1216  $security = ilSecuritySettings::_getInstance();
1217 
1218  // check if password is empty
1219  if( empty($a_passwd) )
1220  {
1221  $customError = $lng->txt('password_empty');
1222  return false;
1223  }
1224 
1225  $isPassword = true;
1226  $errors = array();
1227 
1228  // check if password to short
1229  if( $security->getPasswordMinLength() > 0 && strlen($a_passwd) < $security->getPasswordMinLength() )
1230  {
1231  $errors[] = sprintf( $lng->txt('password_to_short'), $security->getPasswordMinLength() );
1232  $isPassword = false;
1233  }
1234 
1235  // check if password not to long
1236  // Hmmmmm, maybe we should discuss this limitation. In my opinion it is stupid to limit the password length ;-). There should only be a technical limitation (field size in database).
1237  if( $security->getPasswordMaxLength() > 0 && strlen($a_passwd) > $security->getPasswordMaxLength() )
1238  {
1239  $errors[] = sprintf( $lng->txt('password_to_long'), $security->getPasswordMaxLength() );
1240  $isPassword = false;
1241  }
1242 
1243  // if password must contains Chars and Numbers
1244  if( $security->isPasswordCharsAndNumbersEnabled() )
1245  {
1246  $hasCharsAndNumbers = true;
1247 
1248  // check password for existing chars
1249  if( !preg_match('/[A-Za-z]+/',$a_passwd) )
1250  {
1251  $hasCharsAndNumbers = false;
1252  }
1253 
1254  // check password for existing numbers
1255  if( !preg_match('/[0-9]+/',$a_passwd) )
1256  {
1257  $hasCharsAndNumbers = false;
1258  }
1259 
1260  if( !$hasCharsAndNumbers )
1261  {
1262  $errors[] = $lng->txt('password_must_chars_and_numbers');
1263  $isPassword = false;
1264  }
1265  }
1266 
1267  require_once 'Services/Utilities/classes/class.ilStr.php';
1268  if($security->getPasswordNumberOfUppercaseChars() > 0)
1269  {
1270  if(ilStr::strLen($a_passwd) - ilStr::strLen(preg_replace('/[A-Z]/', '', $a_passwd)) < $security->getPasswordNumberOfUppercaseChars())
1271  {
1272  $errors[] = sprintf($lng->txt('password_must_contain_ucase_chars'), $security->getPasswordNumberOfUppercaseChars());
1273  $isPassword = false;
1274  }
1275  }
1276 
1277  if($security->getPasswordNumberOfLowercaseChars() > 0)
1278  {
1279  if(ilStr::strLen($a_passwd) - ilStr::strLen(preg_replace('/[a-z]/', '', $a_passwd)) < $security->getPasswordNumberOfLowercaseChars())
1280  {
1281  $errors[] = sprintf($lng->txt('password_must_contain_lcase_chars'), $security->getPasswordNumberOfLowercaseChars());
1282  $isPassword = false;
1283  }
1284  }
1285 
1286  // if password must contains Special-Chars
1287  if( $security->isPasswordSpecialCharsEnabled() )
1288  {
1289  // check password for existing special-chars
1290  if( !preg_match( self::getPasswordValidChars(true, true) , $a_passwd) )
1291  {
1292  $errors[] = $lng->txt('password_must_special_chars');
1293  $isPassword = false;
1294  }
1295  }
1296 
1297  // ensure password matches the positive list of chars/special-chars
1298  if( !preg_match( self::getPasswordValidChars() , $a_passwd) )
1299  {
1300  $errors[] = $lng->txt('password_contains_invalid_chars');
1301  $isPassword = false;
1302  }
1303 
1304  // build custom error message
1305  if( count($errors) == 1 )
1306  {
1307  $customError = $errors[0];
1308  }
1309  elseif( count($errors) > 1 )
1310  {
1311  $customError = $lng->txt('password_multiple_errors');
1312  $customError .= '<br />'.implode('<br />', $errors);
1313  }
1314 
1315  return $isPassword;
1316  }
1317 
1324  public static function isPasswordValidForUserContext($clear_text_password, $user, &$error_language_variable = null)
1325  {
1326  include_once 'Services/PrivacySecurity/classes/class.ilSecuritySettings.php';
1327  $security = ilSecuritySettings::_getInstance();
1328 
1329  $login = null;
1330 
1331  if(is_string($user))
1332  {
1333  $login = $user;
1334  }
1335  else if(is_array($user))
1336  {
1337  // Try to get loginname and user_id from array
1338  $login = $user['login'];
1339  $userId = $user['id'];
1340  }
1341  else if($user instanceof ilObjUser)
1342  {
1343  $login = $user->getLogin();
1344  $userId = $user->getId();
1345  }
1346 
1347  // The user context (user instance or id) can be used for further validation (e.g. compare a password with the users' password history, etc.) in future releases.
1348 
1349  if($login && (int)$security->getPasswordMustNotContainLoginnameStatus() &&
1350  strpos(strtolower($clear_text_password), strtolower($login)) !== false
1351  )
1352  {
1353  $error_language_variable = 'password_contains_parts_of_login_err';
1354  return false;
1355  }
1356 
1357  return true;
1358  }
1359 
1367  public static function getPasswordValidChars($a_as_regex = true, $a_only_special_chars = false)
1368  {
1369  if( $a_as_regex )
1370  {
1371  if( $a_only_special_chars )
1372  {
1373  return '/[_\.\+\?\#\-\*\@!\$\%\~\/\:\;]+/';
1374  }
1375  else
1376  {
1377  return '/^[A-Za-z0-9_\.\+\?\#\-\*\@!\$\%\~\/\:\;]+$/';
1378  }
1379  }
1380  else
1381  {
1382  return 'A-Z a-z 0-9 _.+?#-*@!$%~/:;';
1383  }
1384  }
1385 
1393  public static function getPasswordRequirementsInfo()
1394  {
1395  global $lng;
1396 
1397  include_once('./Services/PrivacySecurity/classes/class.ilSecuritySettings.php');
1398  $security = ilSecuritySettings::_getInstance();
1399 
1400  $infos = array(sprintf($lng->txt('password_allow_chars'), self::getPasswordValidChars(false)));
1401 
1402  // check if password to short
1403  if( $security->getPasswordMinLength() > 0 )
1404  {
1405  $infos[] = sprintf( $lng->txt('password_to_short'), $security->getPasswordMinLength() );
1406  }
1407 
1408  // check if password not to long
1409  if( $security->getPasswordMaxLength() > 0 )
1410  {
1411  $infos[] = sprintf( $lng->txt('password_to_long'), $security->getPasswordMaxLength() );
1412  }
1413 
1414  // if password must contains Chars and Numbers
1415  if( $security->isPasswordCharsAndNumbersEnabled() )
1416  {
1417  $infos[] = $lng->txt('password_must_chars_and_numbers');
1418  }
1419 
1420  // if password must contains Special-Chars
1421  if( $security->isPasswordSpecialCharsEnabled() )
1422  {
1423  $infos[] = $lng->txt('password_must_special_chars');
1424  }
1425 
1426  if($security->getPasswordNumberOfUppercaseChars() > 0)
1427  {
1428  $infos[] = sprintf($lng->txt('password_must_contain_ucase_chars'), $security->getPasswordNumberOfUppercaseChars());
1429  }
1430 
1431  if($security->getPasswordNumberOfLowercaseChars() > 0)
1432  {
1433  $infos[] = sprintf($lng->txt('password_must_contain_lcase_chars'), $security->getPasswordNumberOfLowercaseChars());
1434  }
1435 
1436  return implode('<br />', $infos);
1437  }
1438 
1439  /*
1440  * validates a login
1441  * @access public
1442  * @param string login
1443  * @return boolean true if valid
1444  */
1445  function isLogin($a_login)
1446  {
1447  if (empty($a_login))
1448  {
1449  return false;
1450  }
1451 
1452  if (strlen($a_login) < 3)
1453  {
1454  return false;
1455  }
1456 
1457  // FIXME - If ILIAS is configured to use RFC 822
1458  // compliant mail addresses we should not
1459  // allow the @ character.
1460  if (!ereg("^[A-Za-z0-9_\.\+\*\@!\$\%\~\-]+$", $a_login))
1461  {
1462  return false;
1463  }
1464 
1465  return true;
1466  }
1467 
1481  public static function shortenText ($a_str, $a_len, $a_dots = false, $a_next_blank = false,
1482  $a_keep_extension = false)
1483  {
1484  include_once("./Services/Utilities/classes/class.ilStr.php");
1485  if (ilStr::strLen($a_str) > $a_len)
1486  {
1487  if ($a_next_blank)
1488  {
1489  $len = ilStr::strPos($a_str, " ", $a_len);
1490  }
1491  else
1492  {
1493  $len = $a_len;
1494  }
1495  // BEGIN WebDAV
1496  // - Shorten names in the middle, before the filename extension
1497  // Workaround for Windows WebDAV Client:
1498  // Use the unicode ellipsis symbol for shortening instead of
1499  // three full stop characters.
1500  if ($a_keep_extension)
1501  {
1502  $p = strrpos($a_str, '.'); // this messes up normal shortening, see bug #6190
1503  }
1504  if ($p === false || $p == 0 || strlen($a_str) - $p > $a_len)
1505  {
1506  $a_str = ilStr::subStr($a_str,0,$len);
1507  if ($a_dots)
1508  {
1509  $a_str .= "\xe2\x80\xa6"; // UTF-8 encoding for Unicode ellipsis character.
1510  }
1511  }
1512  else
1513  {
1514  if ($a_dots)
1515  {
1516  $a_str = ilStr::subStr($a_str,0,$len - (strlen($a_str) - $p + 1))."\xe2\x80\xa6".substr($a_str, $p);
1517  }
1518  else
1519  {
1520  $a_str = ilStr::subStr($a_str,0,$len - (strlen($a_str) - $p + 1)).substr($a_str, $p);
1521  }
1522  }
1523  }
1524 
1525  return $a_str;
1526  }
1527 
1538  public static function shortenWords($a_str, $a_len = 30, $a_dots = true)
1539  {
1540  include_once("./Services/Utilities/classes/class.ilStr.php");
1541  $str_arr = explode(" ", $a_str);
1542 
1543  for ($i = 0; $i < count($str_arr); $i++)
1544  {
1545  if (ilStr::strLen($str_arr[$i]) > $a_len)
1546  {
1547  $str_arr[$i] = ilStr::subStr($str_arr[$i], 0, $a_len);
1548  if ($a_dots)
1549  {
1550  $str_arr[$i].= "...";
1551  }
1552  }
1553  }
1554 
1555  return implode($str_arr, " ");
1556  }
1557 
1567  public static function attribsToArray($a_str)
1568  {
1569  $attribs = array();
1570  while (is_int(strpos($a_str, "=")))
1571  {
1572  $eq_pos = strpos($a_str, "=");
1573  $qu1_pos = strpos($a_str, "\"");
1574  $qu2_pos = strpos(substr($a_str, $qu1_pos + 1), "\"") + $qu1_pos + 1;
1575  if (is_int($eq_pos) && is_int($qu1_pos) && is_int($qu2_pos))
1576  {
1577  $var = trim(substr($a_str, 0, $eq_pos));
1578  $val = trim(substr($a_str, $qu1_pos + 1, ($qu2_pos - $qu1_pos) - 1));
1579  $attribs[$var] = $val;
1580  $a_str = substr($a_str, $qu2_pos + 1);
1581  }
1582  else
1583  {
1584  $a_str = "";
1585  }
1586  }
1587  return $attribs;
1588  }
1589 
1601  public static function rCopy ($a_sdir, $a_tdir, $preserveTimeAttributes = false)
1602  {
1603  // check if arguments are directories
1604  if (!@is_dir($a_sdir) or
1605  !@is_dir($a_tdir))
1606  {
1607  return FALSE;
1608  }
1609 
1610  // read a_sdir, copy files and copy directories recursively
1611  $dir = opendir($a_sdir);
1612 
1613  while($file = readdir($dir))
1614  {
1615  if ($file != "." and
1616  $file != "..")
1617  {
1618  // directories
1619  if (@is_dir($a_sdir."/".$file))
1620  {
1621  if (!@is_dir($a_tdir."/".$file))
1622  {
1623  if (!ilUtil::makeDir($a_tdir."/".$file))
1624  return FALSE;
1625 
1626  //chmod($a_tdir."/".$file, 0775);
1627  }
1628 
1629  if (!ilUtil::rCopy($a_sdir."/".$file,$a_tdir."/".$file))
1630  {
1631  return FALSE;
1632  }
1633  }
1634 
1635  // files
1636  if (@is_file($a_sdir."/".$file))
1637  {
1638  if (!copy($a_sdir."/".$file,$a_tdir."/".$file))
1639  {
1640  return FALSE;
1641  }
1642  if ($preserveTimeAttributes)
1643  touch($a_tdir."/".$file, filectime($a_sdir."/".$file));
1644  }
1645  }
1646  }
1647  return TRUE;
1648  }
1649 
1658  public static function getWebspaceDir($mode = "filesystem")
1659  {
1660  global $ilias;
1661 
1662  if ($mode == "filesystem")
1663  {
1664  return "./".ILIAS_WEB_DIR."/".$ilias->client_id;
1665  }
1666  else
1667  {
1668  if (defined("ILIAS_MODULE"))
1669  {
1670  return "../".ILIAS_WEB_DIR."/".$ilias->client_id;
1671  }
1672  else
1673  {
1674  return "./".ILIAS_WEB_DIR."/".$ilias->client_id;
1675  }
1676  }
1677 
1678  //return $ilias->ini->readVariable("server","webspace_dir");
1679  }
1680 
1687  public static function getDataDir()
1688  {
1689  return CLIENT_DATA_DIR;
1690  //global $ilias;
1691 
1692  //return $ilias->ini->readVariable("server", "data_dir");
1693  }
1694 
1704  public static function getUsersOnline($a_user_id = 0)
1705  {
1706  include_once("./Services/User/classes/class.ilObjUser.php");
1707  return ilObjUser::_getUsersOnline($a_user_id);
1708  }
1709 
1720  public static function getAssociatedUsersOnline($a_user_id)
1721  {
1722  include_once("./Services/User/classes/class.ilObjUser.php");
1723  return ilObjUser::_getAssociatedUsersOnline($a_user_id);
1724  }
1725 
1733  public static function ilTempnam()
1734  {
1735  $temp_path = ilUtil::getDataDir() . "/temp";
1736  if (!is_dir($temp_path))
1737  {
1738  ilUtil::createDirectory($temp_path);
1739  }
1740  $temp_name = tempnam($temp_path, "tmp");
1741  // --->
1742  // added the following line because tempnam creates a backslash on some
1743  // Windows systems which leads to problems, because the "...\tmp..." can be
1744  // interpreted as "...{TAB-CHARACTER}...". The normal slash works fine
1745  // even under windows (Helmut Schottmüller, 2005-08-31)
1746  $temp_name = str_replace("\\", "/", $temp_name);
1747  // --->
1748  unlink($temp_name);
1749  return $temp_name;
1750  }
1751 
1760  public static function createDirectory($a_dir, $a_mod = 0755)
1761  {
1762  ilUtil::makeDir($a_dir);
1763  //@mkdir($a_dir);
1764  //@chmod($a_dir, $a_mod);
1765  }
1766 
1767 
1776  public static function unzip($a_file, $overwrite = false, $a_flat = false)
1777  {
1778  if (!is_file($a_file))
1779  {
1780  return;
1781  }
1782 
1783  // if flat, move file to temp directory first
1784  if ($a_flat)
1785  {
1786  $tmpdir = ilUtil::ilTempnam();
1787  ilUtil::makeDir($tmpdir);
1788  copy($a_file, $tmpdir.DIRECTORY_SEPARATOR.basename($a_file));
1789  $orig_file = $a_file;
1790  $a_file = $tmpdir.DIRECTORY_SEPARATOR.basename($a_file);
1791  $origpathinfo = pathinfo($orig_file);
1792  }
1793 
1794  $pathinfo = pathinfo($a_file);
1795  $dir = $pathinfo["dirname"];
1796  $file = $pathinfo["basename"];
1797 
1798  // unzip
1799  $cdir = getcwd();
1800  chdir($dir);
1801  $unzip = PATH_TO_UNZIP;
1802 
1803  // the following workaround has been removed due to bug
1804  // http://www.ilias.de/mantis/view.php?id=7578
1805  // since the workaround is quite old, it may not be necessary
1806  // anymore, alex 9 Oct 2012
1807 /*
1808  // workaround for unzip problem (unzip of subdirectories fails, so
1809  // we create the subdirectories ourselves first)
1810  // get list
1811  $unzipcmd = "-Z -1 ".ilUtil::escapeShellArg($file);
1812  $arr = ilUtil::execQuoted($unzip, $unzipcmd);
1813  $zdirs = array();
1814 
1815  foreach($arr as $line)
1816  {
1817  if(is_int(strpos($line, "/")))
1818  {
1819  $zdir = substr($line, 0, strrpos($line, "/"));
1820  $nr = substr_count($zdir, "/");
1821  //echo $zdir." ".$nr."<br>";
1822  while ($zdir != "")
1823  {
1824  $nr = substr_count($zdir, "/");
1825  $zdirs[$zdir] = $nr; // collect directories
1826  //echo $dir." ".$nr."<br>";
1827  $zdir = substr($zdir, 0, strrpos($zdir, "/"));
1828  }
1829  }
1830  }
1831 
1832  asort($zdirs);
1833 
1834  foreach($zdirs as $zdir => $nr) // create directories
1835  {
1836  ilUtil::createDirectory($zdir);
1837  }
1838 */
1839 
1840  // real unzip
1841  if (!$overwrite)
1842  {
1843  $unzipcmd = ilUtil::escapeShellArg($file);
1844  }
1845  else
1846  {
1847  $unzipcmd = "-o ".ilUtil::escapeShellArg($file);
1848  }
1849  ilUtil::execQuoted($unzip, $unzipcmd);
1850 
1851  chdir($cdir);
1852 
1853  // if flat, get all files and move them to original directory
1854  if ($a_flat)
1855  {
1856  include_once("./Services/Utilities/classes/class.ilFileUtils.php");
1857  $filearray = array();
1858  ilFileUtils::recursive_dirscan($tmpdir, $filearray);
1859  if (is_array($filearray["file"]))
1860  {
1861  foreach ($filearray["file"] as $k => $f)
1862  {
1863  if (substr($f, 0, 1) != "." && $f != basename($orig_file))
1864  {
1865  copy($filearray["path"][$k].$f, $origpathinfo["dirname"].DIRECTORY_SEPARATOR.$f);
1866  }
1867  }
1868  }
1869  ilUtil::delDir($tmpdir);
1870  }
1871  }
1872 
1879  public static function zip($a_dir, $a_file, $compress_content = false)
1880  {
1881  $cdir = getcwd();
1882 
1883  if($compress_content)
1884  {
1885  $a_dir .="/*";
1886  $pathinfo = pathinfo($a_dir);
1887  chdir($pathinfo["dirname"]);
1888  }
1889 
1890  $pathinfo = pathinfo($a_file);
1891  $dir = $pathinfo["dirname"];
1892  $file = $pathinfo["basename"];
1893 
1894  if(!$compress_content)
1895  {
1896  chdir($dir);
1897  }
1898 
1899  $zip = PATH_TO_ZIP;
1900 
1901  if(!$zip)
1902  {
1903  chdir($cdir);
1904  return false;
1905  }
1906 
1907  if (is_array($a_dir))
1908  {
1909  $source = "";
1910  foreach($a_dir as $dir)
1911  {
1912  $name = basename($dir);
1913  $source.= " ".ilUtil::escapeShellArg($name);
1914  }
1915  }
1916  else
1917  {
1918  $name = basename($a_dir);
1919  if (trim($name) != "*")
1920  {
1921  $source = ilUtil::escapeShellArg($name);
1922  }
1923  else
1924  {
1925  $source = $name;
1926  }
1927  }
1928 
1929  $zipcmd = "-r ".ilUtil::escapeShellArg($a_file)." ".$source;
1930  ilUtil::execQuoted($zip, $zipcmd);
1931  chdir($cdir);
1932  return true;
1933  }
1934 
1935  public static function CreateIsoFromFolder($a_dir, $a_file)
1936  {
1937  $cdir = getcwd();
1938 
1939  $pathinfo = pathinfo($a_dir);
1940  chdir($pathinfo["dirname"]);
1941 
1942  $pathinfo = pathinfo($a_file);
1943  $dir = $pathinfo["dirname"];
1944  $file = $pathinfo["basename"]; $zipcmd = "-r ".ilUtil::escapeShellArg($a_file)." ".$source;
1945 
1946  $mkisofs = PATH_TO_MKISOFS;
1947  if(!$mkisofs)
1948  {
1949  chdir($cdir);
1950  return false;
1951  }
1952 
1953  $name = basename($a_dir);
1954  $source = ilUtil::escapeShellArg($name);
1955 
1956  $zipcmd = "-r -J -o ".$a_file." ".$source;
1957  ilUtil::execQuoted($mkisofs, $zipcmd);
1958  chdir($cdir);
1959  return true;
1960  }
1961 
1970  public static function getConvertCmd()
1971  {
1972  return PATH_TO_CONVERT;
1973  }
1974 
1982  public static function execConvert($args)
1983  {
1984  ilUtil::execQuoted(PATH_TO_CONVERT, $args);
1985  }
1986 
1993  public static function isConvertVersionAtLeast($a_version)
1994  {
1995  $current_version = ilUtil::execQuoted(PATH_TO_CONVERT, "--version");
1996  $current_version = self::processConvertVersion($current_version[0]);
1997  $version = self::processConvertVersion($a_version);
1998  if($current_version >= $version)
1999  {
2000  return true;
2001  }
2002  return false;
2003  }
2004 
2011  protected static function processConvertVersion($a_version)
2012  {
2013  if(preg_match("/([0-9]+)\.([0-9]+)\.([0-9]+)([\.|\-]([0-9]+))?/", $a_version, $match))
2014  {
2015  $version = str_pad($match[1], 2, 0, STR_PAD_LEFT).
2016  str_pad($match[2], 2, 0, STR_PAD_LEFT).
2017  str_pad($match[3], 2, 0, STR_PAD_LEFT).
2018  str_pad($match[5], 2, 0, STR_PAD_LEFT);
2019  return (int)$version;
2020  }
2021  }
2022 
2032  public static function convertImage($a_from, $a_to, $a_target_format = "", $a_geometry = "",
2033  $a_background_color = "")
2034  {
2035  $format_str = ($a_target_format != "")
2036  ? strtoupper($a_target_format).":"
2037  : "";
2038  $geometry = "";
2039  if ($a_geometry != "")
2040  {
2041  if (is_int(strpos($a_geometry, "x")))
2042  {
2043  $geometry = " -geometry ".$a_geometry." ";
2044  }
2045  else
2046  {
2047  $geometry = " -geometry ".$a_geometry."x".$a_geometry." ";
2048  }
2049  }
2050 
2051  $bg_color = ($a_background_color != "")
2052  ? " -background color ".$a_background_color." "
2053  : "";
2054  $convert_cmd = ilUtil::escapeShellArg($a_from)." ".$bg_color.$geometry.ilUtil::escapeShellArg($format_str.$a_to);
2055 
2056  ilUtil::execConvert($convert_cmd);
2057  }
2058 
2069  public static function resizeImage($a_from, $a_to, $a_width, $a_height, $a_constrain_prop = false)
2070  {
2071  if ($a_constrain_prop)
2072  {
2073  $size = " -geometry ".$a_width."x".$a_height." ";
2074  }
2075  else
2076  {
2077  $size = " -resize ".$a_width."x".$a_height."! ";
2078  }
2079  $convert_cmd = ilUtil::escapeShellArg($a_from)." ".$size.ilUtil::escapeShellArg($a_to);
2080 
2081  ilUtil::execConvert($convert_cmd);
2082  }
2083 
2090  public static function img($a_src, $a_alt = "", $a_width = "", $a_height = "", $a_border = 0, $a_id = "")
2091  {
2092  $img = '<img src="'.$a_src.'"';
2093  if ($a_alt != "")
2094  {
2095  $img.= ' alt="'.$a_alt.'" title="'.$a_alt.'"';
2096  }
2097  if ($a_width != "")
2098  {
2099  $img.= ' width="'.$a_width.'"';
2100  }
2101  if ($a_height != "")
2102  {
2103  $img.= ' height="'.$a_height.'"';
2104  }
2105  if ($a_id != "")
2106  {
2107  $img.= ' id="'.$a_id.'"';
2108  }
2109  $img.= ' border="'.(int) $a_border.'"/>';
2110 
2111  return $img;
2112  }
2113 
2121  public static function html2pdf($html, $pdf_file)
2122  {
2123  $html_file = str_replace(".pdf",".html",$pdf_file);
2124 
2125  $fp = fopen( $html_file ,"wb");
2126  fwrite($fp, $html);
2127  fclose($fp);
2128 
2129  ilUtil::htmlfile2pdf($html_file,$pdf_file);
2130  }
2131 
2138  public static function htmlfile2pdf($html_file, $pdf_file)
2139  {
2140  $htmldoc_path = PATH_TO_HTMLDOC;
2141 
2142  $htmldoc = "--no-toc ";
2143  $htmldoc .= "--no-jpeg ";
2144  $htmldoc .= "--webpage ";
2145  $htmldoc .= "--outfile " . ilUtil::escapeShellArg($pdf_file) . " ";
2146  $htmldoc .= "--bodyfont Arial ";
2147  $htmldoc .= "--charset iso-8859-15 ";
2148  $htmldoc .= "--color ";
2149  $htmldoc .= "--size A4 "; // --landscape
2150  $htmldoc .= "--format pdf ";
2151  $htmldoc .= "--footer ... ";
2152  $htmldoc .= "--header ... ";
2153  $htmldoc .= "--left 60 ";
2154  // $htmldoc .= "--right 200 ";
2155  $htmldoc .= $html_file;
2156  ilUtil::execQuoted($htmldoc_path, $htmldoc);
2157 
2158  }
2159 
2166  public static function deliverData($a_data, $a_filename, $mime = "application/octet-stream", $charset = "")
2167  {
2168  $disposition = "attachment"; // "inline" to view file in browser or "attachment" to download to hard disk
2169  // $mime = "application/octet-stream"; // or whatever the mime type is
2170 
2171  include_once './Services/Http/classes/class.ilHTTPS.php';
2172 
2173  //if($_SERVER['HTTPS'])
2174  if( ilHTTPS::getInstance()->isDetected() )
2175  {
2176 
2177  // Added different handling for IE and HTTPS => send pragma after content informations
2181  #header("Pragma: ");
2182  #header("Cache-Control: ");
2183  #header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
2184  #header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
2185  #header("Cache-Control: no-store, no-cache, must-revalidate"); // HTTP/1.1
2186  #header("Cache-Control: post-check=0, pre-check=0", false);
2187  }
2188  else if ($disposition == "attachment")
2189  {
2190  header("Cache-control: private");
2191  }
2192  else
2193  {
2194  header("Cache-Control: no-cache, must-revalidate");
2195  header("Pragma: no-cache");
2196  }
2197 
2198  $ascii_filename = ilUtil::getASCIIFilename($a_filename);
2199 
2200  if (strlen($charset))
2201  {
2202  $charset = "; charset=$charset";
2203  }
2204  header("Content-Type: $mime$charset");
2205  header("Content-Disposition:$disposition; filename=\"".$ascii_filename."\"");
2206  header("Content-Description: ".$ascii_filename);
2207  header("Content-Length: ".(string)(strlen($a_data)));
2208 
2209  //if($_SERVER['HTTPS'])
2210  if( ilHTTPS::getInstance()->isDetected() )
2211  {
2212  header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
2213  header('Pragma: public');
2214  }
2215 
2216  header("Connection: close");
2217  echo $a_data;
2218  exit;
2219  }
2220 
2221  // BEGIN WebDAV: Show file in browser or provide it as attachment
2229  public static function deliverFile($a_file, $a_filename,$a_mime = '', $isInline = false, $removeAfterDelivery = false,
2230  $a_exit_after = true)
2231  {
2232  // should we fail silently?
2233  if(!file_exists($a_file))
2234  {
2235  return false;
2236  }
2237 
2238  if ($isInline) {
2239  $disposition = "inline"; // "inline" to view file in browser
2240  } else {
2241  $disposition = "attachment"; // "attachment" to download to hard disk
2242  //$a_mime = "application/octet-stream"; // override mime type to ensure that no browser tries to show the file anyway.
2243  }
2244  // END WebDAV: Show file in browser or provide it as attachment
2245 
2246  if(strlen($a_mime))
2247  {
2248  $mime = $a_mime;
2249  }
2250  else
2251  {
2252  $mime = "application/octet-stream"; // or whatever the mime type is
2253  }
2254  // BEGIN WebDAV: Removed broken HTTPS code.
2255  // END WebDAV: Removed broken HTTPS code.
2256  if ($disposition == "attachment")
2257  {
2258  header("Cache-control: private");
2259  }
2260  else
2261  {
2262  header("Cache-Control: no-cache, must-revalidate");
2263  header("Pragma: no-cache");
2264  }
2265 
2266  $ascii_filename = ilUtil::getASCIIFilename($a_filename);
2267 
2268  header("Content-Type: $mime");
2269  header("Content-Disposition:$disposition; filename=\"".$ascii_filename."\"");
2270  header("Content-Description: ".$ascii_filename);
2271 
2272  // #7271: if notice gets thrown download will fail in IE
2273  $filesize = @filesize($a_file);
2274  if ($filesize)
2275  {
2276  header("Content-Length: ".(string)$filesize);
2277  }
2278 
2279  include_once './Services/Http/classes/class.ilHTTPS.php';
2280  #if($_SERVER['HTTPS'])
2281  if(ilHTTPS::getInstance()->isDetected())
2282  {
2283  header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
2284  header('Pragma: public');
2285  }
2286 
2287  header("Connection: close");
2288  ilUtil::readFile( $a_file );
2289  if ($removeAfterDelivery)
2290  {
2291  unlink ($a_file);
2292  }
2293  if ($a_exit_after)
2294  {
2295  exit;
2296  }
2297  }
2298 
2299 
2309  public static function readFile($a_file)
2310  {
2311  $chunksize = 1*(1024*1024); // how many bytes per chunk
2312  $buffer = '';
2313  $handle = fopen($a_file, 'rb');
2314  if ($handle === false)
2315  {
2316  return false;
2317  }
2318  while (!feof($handle))
2319  {
2320  $buffer = fread($handle, $chunksize);
2321  print $buffer;
2322  }
2323  return fclose($handle);
2324  }
2325 
2333  public static function getASCIIFilename($a_filename)
2334  {
2335  // The filename must be converted to ASCII, as of RFC 2183,
2336  // section 2.3.
2337 
2349 
2352 
2353  $ascii_filename = htmlentities($a_filename, ENT_NOQUOTES, 'UTF-8');
2354  $ascii_filename = preg_replace('/\&(.)[^;]*;/', '\\1', $ascii_filename);
2355  $ascii_filename = preg_replace('/[\x7f-\xff]/', '_', $ascii_filename);
2356 
2357  // OS do not allow the following characters in filenames: \/:*?"<>|
2358  $ascii_filename = preg_replace('/[:\x5c\/\*\?\"<>\|]/', '_', $ascii_filename);
2359 
2360  return $ascii_filename;
2361  }
2362 
2369  public static function htmlentitiesOutsideHTMLTags($htmlText)
2370  {
2371  $matches = Array();
2372  $sep = '###HTMLTAG###';
2373 
2374  preg_match_all("@<[^>]*>@", $htmlText, $matches);
2375  $tmp = preg_replace("@(<[^>]*>)@", $sep, $htmlText);
2376  $tmp = explode($sep, $tmp);
2377 
2378  for ($i=0; $i<count($tmp); $i++)
2379  $tmp[$i] = htmlentities($tmp[$i], ENT_COMPAT, "UTF-8");
2380 
2381  $tmp = join($sep, $tmp);
2382 
2383  for ($i=0; $i<count($matches[0]); $i++)
2384  $tmp = preg_replace("@$sep@", $matches[0][$i], $tmp, 1);
2385 
2386  return $tmp;
2387  }
2388 
2395  public static function getJavaPath()
2396  {
2397  return PATH_TO_JAVA;
2398  //global $ilias;
2399 
2400  //return $ilias->getSetting("java_path");
2401  }
2402 
2410  public static function appendUrlParameterString($a_url, $a_par, $xml_style = false)
2411  {
2412  $amp = $xml_style
2413  ? "&amp;"
2414  : "&";
2415 
2416  $url = (is_int(strpos($a_url, "?")))
2417  ? $a_url.$amp.$a_par
2418  : $a_url."?".$a_par;
2419 
2420  return $url;
2421  }
2422 
2438  public static function makeDir($a_dir)
2439  {
2440  $a_dir = trim($a_dir);
2441 
2442  // remove trailing slash (bugfix for php 4.2.x)
2443  if (substr($a_dir,-1) == "/")
2444  {
2445  $a_dir = substr($a_dir,0,-1);
2446  }
2447 
2448  // check if a_dir comes with a path
2449  if (!($path = substr($a_dir,0, strrpos($a_dir,"/") - strlen($a_dir))))
2450  {
2451  $path = ".";
2452  }
2453 
2454  // create directory with file permissions of parent directory
2455  umask(0000);
2456  return @mkdir($a_dir,fileperms($path));
2457  }
2458 
2459 
2474  public static function makeDirParents($a_dir)
2475  {
2476  $dirs = array($a_dir);
2477  $a_dir = dirname($a_dir);
2478  $last_dirname = '';
2479 
2480  while($last_dirname != $a_dir)
2481  {
2482  array_unshift($dirs, $a_dir);
2483  $last_dirname = $a_dir;
2484  $a_dir = dirname($a_dir);
2485  }
2486 
2487  // find the first existing dir
2488  $reverse_paths = array_reverse($dirs, TRUE);
2489  $found_index = -1;
2490  foreach ($reverse_paths as $key => $value)
2491  {
2492  if ($found_index == -1)
2493  {
2494  if (is_dir($value))
2495  {
2496  $found_index = $key;
2497  }
2498  }
2499  }
2500 
2501  umask(0000);
2502  foreach ($dirs as $dirindex => $dir)
2503  {
2504  // starting with the longest existing path
2505  if ($dirindex >= $found_index)
2506  {
2507  if (! file_exists($dir))
2508  {
2509  if (strcmp(substr($dir,strlen($dir)-1,1),"/") == 0)
2510  {
2511  // on some systems there is an error when there is a slash
2512  // at the end of a directory in mkdir, see Mantis #2554
2513  $dir = substr($dir,0,strlen($dir)-1);
2514  }
2515  if (! mkdir($dir, $umask))
2516  {
2517  error_log("Can't make directory: $dir");
2518  return false;
2519  }
2520  }
2521  elseif (! is_dir($dir))
2522  {
2523  error_log("$dir is not a directory");
2524  return false;
2525  }
2526  else
2527  {
2528  // get umask of the last existing parent directory
2529  $umask = fileperms($dir);
2530  }
2531  }
2532  }
2533  return true;
2534  }
2535 
2545  public static function delDir($a_dir, $a_clean_only = false)
2546  {
2547  if (!is_dir($a_dir) || is_int(strpos($a_dir, "..")))
2548  {
2549  return;
2550  }
2551 
2552  $current_dir = opendir($a_dir);
2553 
2554  $files = array();
2555 
2556  // this extra loop has been necessary because of a strange bug
2557  // at least on MacOS X. A looped readdir() didn't work
2558  // correctly with larger directories
2559  // when an unlink happened inside the loop. Getting all files
2560  // into the memory first solved the problem.
2561  while($entryname = readdir($current_dir))
2562  {
2563  $files[] = $entryname;
2564  }
2565 
2566  foreach($files as $file)
2567  {
2568  if(is_dir($a_dir."/".$file) and ($file != "." and $file!=".."))
2569  {
2570  ilUtil::delDir(${a_dir}."/".${file});
2571  }
2572  elseif ($file != "." and $file != "..")
2573  {
2574  unlink(${a_dir}."/".${file});
2575  }
2576  }
2577 
2578  closedir($current_dir);
2579  if (!$a_clean_only)
2580  {
2581  @rmdir(${a_dir});
2582  }
2583  }
2584 
2585 
2592  public static function getDir($a_dir, $a_rec = false, $a_sub_dir = "")
2593  {
2594  $current_dir = opendir($a_dir.$a_sub_dir);
2595 
2596  $dirs = array();
2597  $files = array();
2598  $subitems = array();
2599  while($entry = readdir($current_dir))
2600  {
2601  if(is_dir($a_dir."/".$entry))
2602  {
2603  $dirs[$entry] = array("type" => "dir", "entry" => $entry,
2604  "subdir" => $a_sub_dir);
2605  if ($a_rec && $entry != "." && $entry != "..")
2606  {
2607  $si = ilUtil::getDir($a_dir, true, $a_sub_dir."/".$entry);
2608  $subitems = array_merge($subitems, $si);
2609  }
2610  }
2611  else
2612  {
2613  if ($entry != "." && $entry != "..")
2614  {
2615  $size = filesize($a_dir.$a_sub_dir."/".$entry);
2616  $files[$entry] = array("type" => "file", "entry" => $entry,
2617  "size" => $size, "subdir" => $a_sub_dir);
2618  }
2619  }
2620  }
2621  ksort($dirs);
2622  ksort($files);
2623 
2624  return array_merge($dirs, $files, $subitems);
2625  }
2626 
2633  public static function stripSlashesArray($a_arr, $a_strip_html = true, $a_allow = "")
2634  {
2635  if (is_array($a_arr))
2636  {
2637  foreach ($a_arr as $k => $v)
2638  {
2639  $a_arr[$k] = ilUtil::stripSlashes($v, $a_strip_html, $a_allow);
2640  }
2641  }
2642 
2643  return $a_arr;
2644  }
2645 
2652  public static function stripSlashesRecursive($a_data, $a_strip_html = true, $a_allow = "")
2653  {
2654  if (is_array($a_data))
2655  {
2656  foreach ($a_data as $k => $v)
2657  {
2658  if (is_array($v))
2659  {
2660  $a_data[$k] = ilUtil::stripSlashesRecursive($v, $a_strip_html, $a_allow);
2661  }
2662  else
2663  {
2664  $a_data[$k] = ilUtil::stripSlashes($v, $a_strip_html, $a_allow);
2665  }
2666  }
2667  }
2668  else
2669  {
2670  $a_data = ilUtil::stripSlashes($a_data, $a_strip_html, $a_allow);
2671  }
2672 
2673  return $a_data;
2674  }
2675 
2683  public static function stripSlashes($a_str, $a_strip_html = true, $a_allow = "")
2684  {
2685  if (ini_get("magic_quotes_gpc"))
2686  {
2687  $a_str = stripslashes($a_str);
2688  }
2689 //echo "<br><br>-".$a_strip_html."-".htmlentities($a_str);
2690 //echo "<br>-".htmlentities(ilUtil::secureString($a_str, $a_strip_html, $a_allow));
2691  return ilUtil::secureString($a_str, $a_strip_html, $a_allow);
2692  }
2693 
2701  public static function stripOnlySlashes($a_str)
2702  {
2703  if (ini_get("magic_quotes_gpc"))
2704  {
2705  $a_str = stripslashes($a_str);
2706  }
2707 
2708  return $a_str;
2709  }
2710 
2717  public static function secureString($a_str, $a_strip_html = true, $a_allow = "")
2718  {
2719  // check whether all allowed tags can be made secure
2720  $only_secure = true;
2721  $allow_tags = explode(">", $a_allow);
2722  $sec_tags = ilUtil::getSecureTags();
2723  $allow_array = array();
2724  foreach($allow_tags as $allow)
2725  {
2726  if ($allow != "")
2727  {
2728  $allow = str_replace("<", "", $allow);
2729 
2730  if (!in_array($allow, $sec_tags))
2731  {
2732  $only_secure = false;
2733  }
2734  $allow_array[] = $allow;
2735  }
2736  }
2737 
2738  // default behaviour: allow only secure tags 1:1
2739  if (($only_secure || $a_allow == "") && $a_strip_html)
2740  {
2741  if ($a_allow == "")
2742  {
2743  $allow_array = array ("b", "i", "strong", "em", "code", "cite",
2744  "gap", "sub", "sup", "pre", "strike");
2745  }
2746 
2747  // this currently removes parts of strings like "a <= b"
2748  // because "a <= b" is treated like "<spam onclick='hurt()'>ss</spam>"
2749  $a_str = ilUtil::maskSecureTags($a_str, $allow_array);
2750  $a_str = strip_tags($a_str); // strip all other tags
2751  $a_str = ilUtil::unmaskSecureTags($a_str, $allow_array);
2752 
2753  // a possible solution could be something like:
2754  // $a_str = str_replace("<", "&lt;", $a_str);
2755  // $a_str = str_replace(">", "&gt;", $a_str);
2756  // $a_str = ilUtil::unmaskSecureTags($a_str, $allow_array);
2757  //
2758  // output would be ok then, but input fields would show
2759  // "a &lt;= b" for input "a <= b" if data is brought back to a form
2760  }
2761  else
2762  {
2763  // only for scripts, that need to allow more/other tags and parameters
2764  if ($a_strip_html)
2765  {
2766  $a_str = ilUtil::stripScriptHTML($a_str, $a_allow);
2767  }
2768  }
2769 
2770  return $a_str;
2771  }
2772 
2773  public static function getSecureTags()
2774  {
2775  return array("strong", "em", "u", "strike", "ol", "li", "ul", "p", "div",
2776  "i", "b", "code", "sup", "sub", "pre", "gap", "a", "img");
2777  }
2778 
2779  public static function maskSecureTags($a_str, $allow_array)
2780  {
2781  foreach ($allow_array as $t)
2782  {
2783  switch($t)
2784  {
2785  case "a":
2786  $a_str = ilUtil::maskAttributeTag($a_str, "a", "href");
2787  break;
2788 
2789  case "img":
2790  $a_str = ilUtil::maskAttributeTag($a_str, "img", "src");
2791  break;
2792 
2793  case "p":
2794  case "div":
2795  $a_str = ilUtil::maskTag($a_str, $t, array(
2796  array("param" => "align", "value" => "left"),
2797  array("param" => "align", "value" => "center"),
2798  array("param" => "align", "value" => "justify"),
2799  array("param" => "align", "value" => "right")
2800  ));
2801  break;
2802 
2803  default:
2804  $a_str = ilUtil::maskTag($a_str, $t);
2805  break;
2806  }
2807  }
2808 
2809  return $a_str;
2810  }
2811 
2812  public static function unmaskSecureTags($a_str, $allow_array)
2813  {
2814  foreach ($allow_array as $t)
2815  {
2816  switch($t)
2817  {
2818  case "a":
2819  $a_str = ilUtil::unmaskAttributeTag($a_str, "a", "href");
2820  break;
2821 
2822  case "img":
2823  $a_str = ilUtil::unmaskAttributeTag($a_str, "img", "src");
2824  break;
2825 
2826  case "p":
2827  case "div":
2828  $a_str = ilUtil::unmaskTag($a_str, $t, array(
2829  array("param" => "align", "value" => "left"),
2830  array("param" => "align", "value" => "center"),
2831  array("param" => "align", "value" => "justify"),
2832  array("param" => "align", "value" => "right")
2833  ));
2834  break;
2835 
2836  default:
2837  $a_str = ilUtil::unmaskTag($a_str, $t);
2838  break;
2839  }
2840  }
2841 
2842  return $a_str;
2843  }
2844 
2852  public static function securePlainString($a_str)
2853  {
2854  if (ini_get("magic_quotes_gpc"))
2855  {
2856  return stripslashes($a_str);
2857  }
2858  else
2859  {
2860  return $a_str;
2861  }
2862  }
2879  public static function htmlencodePlainString($a_str, $a_make_links_clickable, $a_detect_goto_links = false)
2880  {
2881  $encoded = "";
2882 
2883  if ($a_make_links_clickable)
2884  {
2885  // Find text sequences in the plain text string which match
2886  // the URI syntax rules, and pass them to ilUtil::makeClickable.
2887  // Encode all other text sequences in the plain text string using
2888  // htmlspecialchars and nl2br.
2889  // The following expressions matches URI's as specified in RFC 2396.
2890  //
2891  // The expression matches URI's, which start with some well known
2892  // schemes, like "http:", or with "www.". This must be followed
2893  // by at least one of the following RFC 2396 expressions:
2894  // - alphanum: [a-zA-Z0-9]
2895  // - reserved: [;\/?:|&=+$,]
2896  // - mark: [\\-_.!~*\'()]
2897  // - escaped: %[0-9a-fA-F]{2}
2898  // - fragment delimiter: #
2899  // - uric_no_slash: [;?:@&=+$,]
2900  $matches = array();
2901  $numberOfMatches = preg_match_all('/(?:(?:http|https|ftp|ftps|mailto):|www\.)(?:[a-zA-Z0-9]|[;\/?:|&=+$,]|[\\-_.!~*\'()]|%[0-9a-fA-F]{2}|#|[;?:@&=+$,])+/',$a_str, $matches, PREG_OFFSET_CAPTURE);
2902  $pos1 = 0;
2903  $encoded = "";
2904  foreach ($matches as $match)
2905  {
2906  }
2907  foreach ($matches[0] as $match)
2908  {
2909  $matched_text = $match[0];
2910  $pos2 = $match[1];
2911  if ($matched_offset != previous_offset)
2912  {
2913  // encode plain text
2914  $encoded .= nl2br(htmlspecialchars(substr($a_str, $pos1, $pos2 - $pos1)));
2915  }
2916  // encode URI
2917  $encoded .= ilUtil::makeClickable($matched_text, $a_detect_goto_links);
2918 
2919 
2920  $pos1 = $pos2 + strlen($matched_text);
2921  }
2922  if ($pos1 < strlen($a_str))
2923  {
2924  $encoded .= nl2br(htmlspecialchars(substr($a_str, $pos1)));
2925  }
2926  }
2927  else
2928  {
2929  $encoded = nl2br(htmlspecialchars($a_str));
2930  }
2931  return $encoded;
2932  }
2933 
2934 
2935  public static function maskAttributeTag($a_str, $tag, $tag_att)
2936  {
2937  global $ilLog;
2938 
2939  $ws = "[ \t\r\f\v\n]*";
2940  $att = $ws."[^>]*".$ws;
2941 
2942  while (eregi("<($tag$att($tag_att$ws=$ws\"(([\$@!*()~;,_0-9A-z/:=%\\.&#?+\\-])*)\")$att)>",
2943  $a_str, $found))
2944  {
2945  $un = array(".", "-", "+", "?", '$', "*", "(", ")");
2946  $esc = array();
2947  foreach($un as $v)
2948  {
2949  $esc[] = "\\".$v;
2950  }
2951  $ff = str_replace($un, $esc, $found[1]);
2952 
2953  $old_str = $a_str;
2954  $a_str = eregi_replace("<".$ff.">",
2955  "&lt;$tag $tag_att$tag_att=\"".$found[3]."\"&gt;", $a_str);
2956  if ($old_str == $a_str)
2957  {
2958  $ilLog->write("ilUtil::maskA-".htmlentities($old_str)." == ".
2959  htmlentities($a_str));
2960  return $a_str;
2961  }
2962  }
2963  $a_str = str_ireplace("</$tag>",
2964  "&lt;/$tag&gt;", $a_str);
2965  return $a_str;
2966  }
2967 
2968  public static function unmaskAttributeTag($a_str, $tag, $tag_att)
2969  {
2970  global $ilLog;
2971 
2972  while (eregi("&lt;($tag $tag_att$tag_att=\"(([\$@!*()~;,_0-9A-z/:=%\\.&#?+\\-])*)\")&gt;",
2973  $a_str, $found))
2974  {
2975  $un = array(".", "-", "+", "?", '$', "*", "(", ")");
2976  $esc = array();
2977  foreach($un as $v)
2978  {
2979  $esc[] = "\\".$v;
2980  }
2981  $ff = str_replace($un, $esc, $found[1]);
2982 
2983  $old_str = $a_str;
2984  $a_str = eregi_replace("&lt;".$ff."&gt;",
2985  "<$tag $tag_att=\"".ilUtil::secureLink($found[2])."\">", $a_str);
2986  if ($old_str == $a_str)
2987  {
2988  $ilLog->write("ilUtil::unmaskA-".htmlentities($old_str)." == ".
2989  htmlentities($a_str));
2990  return $a_str;
2991  }
2992  }
2993  $a_str = str_replace("&lt;/$tag&gt;", "</$tag>", $a_str);
2994  return $a_str;
2995  }
2996 
2997  public static function maskTag($a_str, $t, $fix_param = "")
2998  {
2999  $a_str = str_replace(array("<$t>", "<".strtoupper($t).">"),
3000  "&lt;".$t."&gt;", $a_str);
3001  $a_str = str_replace(array("</$t>", "</".strtoupper($t).">"),
3002  "&lt;/".$t."&gt;", $a_str);
3003 
3004  if (is_array($fix_param))
3005  {
3006  foreach ($fix_param as $p)
3007  {
3008  $k = $p["param"];
3009  $v = $p["value"];
3010  $a_str = str_replace("<$t $k=\"$v\">",
3011  "&lt;"."$t $k=\"$v\""."&gt;", $a_str);
3012  }
3013  }
3014 
3015  return $a_str;
3016  }
3017 
3018  public static function unmaskTag($a_str, $t, $fix_param = "")
3019  {
3020  $a_str = str_replace("&lt;".$t."&gt;", "<".$t.">", $a_str);
3021  $a_str = str_replace("&lt;/".$t."&gt;", "</".$t.">", $a_str);
3022 
3023  if (is_array($fix_param))
3024  {
3025  foreach ($fix_param as $p)
3026  {
3027  $k = $p["param"];
3028  $v = $p["value"];
3029  $a_str = str_replace("&lt;$t $k=\"$v\"&gt;",
3030  "<"."$t $k=\"$v\"".">", $a_str);
3031  }
3032  }
3033  return $a_str;
3034  }
3035 
3036  public static function secureLink($a_str)
3037  {
3038  $a_str = str_ireplace("javascript", "jvscrpt", $a_str);
3039  $a_str = str_ireplace(array("%00", "%0a", "%0d", "%1a", "&#00;", "&#x00;",
3040  "&#0;", "&#x0;", "&#x0a;", "&#x0d;", "&#10;", "&#13;"), "-", $a_str);
3041  return $a_str;
3042  }
3043 
3057  public static function stripScriptHTML($a_str, $a_allow = "", $a_rm_js = true)
3058  {
3059  //$a_str = strip_tags($a_str, $a_allow);
3060 
3061  $negativestr = "a,abbr,acronym,address,applet,area,b,base,basefont,".
3062  "bdo,big,blockquote,body,br,button,caption,center,cite,code,col,".
3063  "colgroup,dd,del,dfn,dir,div,dl,dt,em,fieldset,font,form,frame,".
3064  "frameset,h1,h2,h3,h4,h5,h6,head,hr,html,i,iframe,img,input,ins,isindex,kbd,".
3065  "label,legend,li,link,map,menu,meta,noframes,noscript,object,ol,".
3066  "optgroup,option,p,param,q,s,samp,script,select,small,span,".
3067  "strike,strong,style,sub,sup,table,tbody,td,textarea,tfoot,th,thead,".
3068  "title,tr,tt,u,ul,var";
3069  $a_allow = strtolower ($a_allow);
3070  $negatives = explode(",",$negativestr);
3071  $outer_old_str = "";
3072  while($outer_old_str != $a_str)
3073  {
3074  $outer_old_str = $a_str;
3075  foreach ($negatives as $item)
3076  {
3077  $pos = strpos($a_allow, "<$item>");
3078 
3079  // remove complete tag, if not allowed
3080  if ($pos === false)
3081  {
3082  $old_str = "";
3083  while($old_str != $a_str)
3084  {
3085  $old_str = $a_str;
3086  $a_str = preg_replace("/<\/?\s*$item(\/?)\s*>/i", "", $a_str);
3087  $a_str = preg_replace("/<\/?\s*$item(\/?)\s+([^>]*)>/i", "", $a_str);
3088  }
3089  }
3090  }
3091  }
3092 
3093  if ($a_rm_js)
3094  {
3095  // remove all attributes if an "on..." attribute is given
3096  $a_str = preg_replace("/<\s*\w*(\/?)(\s+[^>]*)?(\s+on[^>]*)>/i", "", $a_str);
3097 
3098  // remove all attributes if a "javascript" is within tag
3099  $a_str = preg_replace("/<\s*\w*(\/?)\s+[^>]*javascript[^>]*>/i", "", $a_str);
3100 
3101  // remove all attributes if an "expression" is within tag
3102  // (IE allows something like <b style='width:expression(alert(1))'>test</b>)
3103  $a_str = preg_replace("/<\s*\w*(\/?)\s+[^>]*expression[^>]*>/i", "", $a_str);
3104  }
3105 
3106  return $a_str;
3107  }
3108 
3109 
3118  public static function addSlashes($a_str)
3119  {
3120  if (ini_get("magic_quotes_gpc"))
3121  {
3122  return $a_str;
3123  }
3124  else
3125  {
3126  return addslashes($a_str);
3127  }
3128  }
3129 
3141  public static function prepareFormOutput($a_str, $a_strip = false)
3142  {
3143  if($a_strip)
3144  {
3145  $a_str = ilUtil::stripSlashes($a_str);
3146  }
3147  $a_str = htmlspecialchars($a_str);
3148  // Added replacement of curly brackets to prevent
3149  // problems with PEAR templates, because {xyz} will
3150  // be removed as unused template variable
3151  $a_str = str_replace("{", "&#123;", $a_str);
3152  $a_str = str_replace("}", "&#125;", $a_str);
3153  // needed for LaTeX conversion \\ in LaTeX is a line break
3154  // but without this replacement, php changes \\ to \
3155  $a_str = str_replace("\\", "&#92;", $a_str);
3156  return $a_str;
3157  }
3158 
3159 
3169  public static function prepareDBString($a_str)
3170  {
3171  return addslashes($a_str);
3172  }
3173 
3174 
3183  public static function removeItemFromDesktops($a_id)
3184  {
3185  return ilObjUser::_removeItemFromDesktops($a_id);
3186  }
3187 
3188 
3198  public static function extractParameterString($a_parstr)
3199  {
3200  // parse parameters in array
3201  $par = array();
3202  $ok=true;
3203  while(($spos=strpos($a_parstr,"=")) && $ok)
3204  {
3205  // extract parameter
3206  $cpar = substr($a_parstr,0,$spos);
3207  $a_parstr = substr($a_parstr,$spos,strlen($a_parstr)-$spos);
3208  while(substr($cpar,0,1)=="," ||substr($cpar,0,1)==" " || substr($cpar,0,1)==chr(13) || substr($cpar,0,1)==chr(10))
3209  $cpar = substr($cpar,1,strlen($cpar)-1);
3210  while(substr($cpar,strlen($cpar)-1,1)==" " || substr($cpar,strlen($cpar)-1,1)==chr(13) || substr($cpar,strlen($cpar)-1,1)==chr(10))
3211  $cpar = substr($cpar,0,strlen($cpar)-1);
3212 
3213  // parameter name should only
3214  $cpar_old = "";
3215  while($cpar != $cpar_old)
3216  {
3217  $cpar_old = $cpar;
3218  $cpar = eregi_replace("[^a-zA-Z0-9_]", "", $cpar);
3219  }
3220 
3221  // extract value
3222  if ($cpar != "")
3223  {
3224  if($spos=strpos($a_parstr,"\""))
3225  {
3226  $a_parstr = substr($a_parstr,$spos+1,strlen($a_parstr)-$spos);
3227  $spos=strpos($a_parstr,"\"");
3228  if(is_int($spos))
3229  {
3230  $cval = substr($a_parstr,0,$spos);
3231  $par[$cpar]=$cval;
3232  $a_parstr = substr($a_parstr,$spos+1,strlen($a_parstr)-$spos-1);
3233  }
3234  else
3235  $ok=false;
3236  }
3237  else
3238  $ok=false;
3239  }
3240  }
3241 
3242  if($ok) return $par; else return false;
3243  }
3244 
3245  public static function assembleParameterString($a_par_arr)
3246  {
3247  if (is_array($a_par_arr))
3248  {
3249  $target_arr = array();
3250  foreach ($a_par_arr as $par => $val)
3251  {
3252  $target_arr[] = "$par=\"$val\"";
3253  }
3254  $target_str = implode(", ", $target_arr);
3255  }
3256 
3257  return $target_str;
3258  }
3259 
3266  public static function dumpString($a_str)
3267  {
3268  $ret = $a_str.": ";
3269  for($i=0; $i<strlen($a_str); $i++)
3270  {
3271  $ret.= ord(substr($a_str,$i,1))." ";
3272  }
3273  return $ret;
3274  }
3275 
3276 
3283  public static function yn2tf($a_yn)
3284  {
3285  if(strtolower($a_yn) == "y")
3286  {
3287  return true;
3288  }
3289  else
3290  {
3291  return false;
3292  }
3293  }
3294 
3301  public static function tf2yn($a_tf)
3302  {
3303  if($a_tf)
3304  {
3305  return "y";
3306  }
3307  else
3308  {
3309  return "n";
3310  }
3311  }
3312 
3323  public static function sort_func ($a, $b)
3324  {
3325  global $array_sortby,$array_sortorder;
3326 
3327  // this comparison should give optimal results if
3328  // locale is provided and mb string functions are supported
3329  if ($array_sortorder == "asc")
3330  {
3331  return ilStr::strCmp($a[$array_sortby], $b[$array_sortby]);
3332  }
3333 
3334  if ($array_sortorder == "desc")
3335  {
3336  return !ilStr::strCmp($a[$array_sortby], $b[$array_sortby]);
3337  return strcoll(ilStr::strToUpper($b[$array_sortby]), ilStr::strToUpper($a[$array_sortby]));
3338  }
3339  }
3340 
3351  public static function sort_func_numeric ($a, $b)
3352  {
3353  global $array_sortby,$array_sortorder;
3354 
3355  if ($array_sortorder == "asc")
3356  {
3357  return $a["$array_sortby"] > $b["$array_sortby"];
3358  }
3359 
3360  if ($array_sortorder == "desc")
3361  {
3362  return $a["$array_sortby"] < $b["$array_sortby"];
3363  }
3364  }
3377  public static function sortArray($array,$a_array_sortby,$a_array_sortorder = 0,$a_numeric = false,
3378  $a_keep_keys = false)
3379  {
3380  include_once("./Services/Utilities/classes/class.ilStr.php");
3381 
3382  // BEGIN WebDAV: Provide a 'stable' sort algorithm
3383  if (! $a_keep_keys) {
3384  return self::stableSortArray($array,$a_array_sortby,$a_array_sortorder,$a_numeric,$a_keep_keys);
3385  }
3386  // END WebDAV Provide a 'stable' sort algorithm
3387 
3388  global $array_sortby,$array_sortorder;
3389 
3390  $array_sortby = $a_array_sortby;
3391 
3392  if ($a_array_sortorder == "desc")
3393  {
3394  $array_sortorder = "desc";
3395  }
3396  else
3397  {
3398  $array_sortorder = "asc";
3399  }
3400  if($a_numeric)
3401  {
3402  if ($a_keep_keys)
3403  {
3404  uasort($array, array("ilUtil", "sort_func_numeric"));
3405  }
3406  else
3407  {
3408  usort($array, array("ilUtil", "sort_func_numeric"));
3409  }
3410  }
3411  else
3412  {
3413  if ($a_keep_keys)
3414  {
3415  uasort($array, array("ilUtil", "sort_func"));
3416  }
3417  else
3418  {
3419  usort($array, array("ilUtil", "sort_func"));
3420  }
3421  }
3422  //usort($array,"ilUtil::sort_func");
3423 
3424  return $array;
3425  }
3426  // BEGIN WebDAV: Provide a 'stable' sort algorithm
3441  public static function stableSortArray($array,$a_array_sortby,$a_array_sortorder = 0,$a_numeric = false)
3442  {
3443  global $array_sortby,$array_sortorder;
3444 
3445  $array_sortby = $a_array_sortby;
3446 
3447  if ($a_array_sortorder == "desc")
3448  {
3449  $array_sortorder = "desc";
3450  }
3451  else
3452  {
3453  $array_sortorder = "asc";
3454  }
3455 
3456  // Create a copy of the array values for sorting
3457  $sort_array = array_values($array);
3458 
3459  if($a_numeric)
3460  {
3461  ilUtil::mergesort($sort_array, array("ilUtil", "sort_func_numeric"));
3462  }
3463  else
3464  {
3465  ilUtil::mergesort($sort_array, array("ilUtil", "sort_func"));
3466  }
3467 
3468  return $sort_array;
3469  }
3470  public static function mergesort(&$array, $cmp_function = 'strcmp') {
3471  // Arrays of size < 2 require no action.
3472  if (count($array) < 2) return;
3473 
3474  // Split the array in half
3475  $halfway = count($array) / 2;
3476  $array1 = array_slice($array, 0, $halfway);
3477  $array2 = array_slice($array, $halfway);
3478 
3479  // Recurse to sort the two halves
3480  ilUtil::mergesort($array1, $cmp_function);
3481  ilUtil::mergesort($array2, $cmp_function);
3482 
3483  // If all of $array1 is <= all of $array2, just append them.
3484  if (call_user_func($cmp_function, end($array1), $array2[0]) < 1) {
3485  $array = array_merge($array1, $array2);
3486  return;
3487  }
3488 
3489  // Merge the two sorted arrays into a single sorted array
3490  $array = array();
3491  $ptr1 = $ptr2 = 0;
3492  while ($ptr1 < count($array1) && $ptr2 < count($array2)) {
3493  if (call_user_func($cmp_function, $array1[$ptr1], $array2[$ptr2]) < 1) {
3494  $array[] = $array1[$ptr1++];
3495  }
3496  else {
3497  $array[] = $array2[$ptr2++];
3498  }
3499  }
3500 
3501  // Merge the remainder
3502  while ($ptr1 < count($array1)) $array[] = $array1[$ptr1++];
3503  while ($ptr2 < count($array2)) $array[] = $array2[$ptr2++];
3504 
3505  return;
3506  }
3507  // END WebDAV: Provide a 'stable' sort algorithm
3508 
3520  public static function unique_multi_array($array, $sub_key)
3521  {
3522  $target = array();
3523  $existing_sub_key_values = array();
3524 
3525  foreach ($array as $key=>$sub_array)
3526  {
3527  if (!in_array($sub_array[$sub_key], $existing_sub_key_values))
3528  {
3529  $existing_sub_key_values[] = $sub_array[$sub_key];
3530  $target[$key] = $sub_array;
3531  }
3532  }
3533 
3534  return $target;
3535  }
3536 
3537 
3547  public static function getGDSupportedImageType($a_desired_type)
3548  {
3549  $a_desired_type = strtolower($a_desired_type);
3550  // get supported Image Types
3551  $im_types = ImageTypes();
3552 
3553  switch($a_desired_type)
3554  {
3555  case "jpg":
3556  if ($im_types & IMG_JPG) return "jpg";
3557  if ($im_types & IMG_GIF) return "gif";
3558  if ($im_types & IMG_PNG) return "png";
3559  break;
3560 
3561  case "gif":
3562  if ($im_types & IMG_GIF) return "gif";
3563  if ($im_types & IMG_JPG) return "jpg";
3564  if ($im_types & IMG_PNG) return "png";
3565  break;
3566 
3567  case "png":
3568  if ($im_types & IMG_PNG) return "png";
3569  if ($im_types & IMG_JPG) return "jpg";
3570  if ($im_types & IMG_GIF) return "gif";
3571  break;
3572  }
3573 
3574  return "";
3575  }
3576 
3586  public static function deducibleSize($a_mime)
3587  {
3588  if (($a_mime == "image/gif") || ($a_mime == "image/jpeg") ||
3589  ($a_mime == "image/png") || ($a_mime == "application/x-shockwave-flash") ||
3590  ($a_mime == "image/tiff") || ($a_mime == "image/x-ms-bmp") ||
3591  ($a_mime == "image/psd") || ($a_mime == "image/iff"))
3592  {
3593  return true;
3594  }
3595  else
3596  {
3597  return false;
3598  }
3599  }
3600 
3601 
3609  public static function redirect($a_script)
3610  {
3611  global $log, $PHP_SELF;
3612 
3613 //echo "<br>".$a_script;
3614  if (!is_int(strpos($a_script, "://")))
3615  {
3616  if (substr($a_script, 0, 1) != "/" && defined("ILIAS_HTTP_PATH"))
3617  {
3618  if (is_int(strpos($_SERVER["PHP_SELF"], "/setup/")))
3619  {
3620  $a_script = "setup/".$a_script;
3621  }
3622  $a_script = ILIAS_HTTP_PATH."/".$a_script;
3623  }
3624  }
3625 //echo "<br>".$a_script; exit;
3626 
3627  // include the user interface hook
3628  global $ilPluginAdmin;
3629  if (is_object($ilPluginAdmin))
3630  {
3631  $pl_names = $ilPluginAdmin->getActivePluginsForSlot(IL_COMP_SERVICE, "UIComponent", "uihk");
3632  foreach ($pl_names as $pl)
3633  {
3634  $ui_plugin = ilPluginAdmin::getPluginObject(IL_COMP_SERVICE, "UIComponent", "uihk", $pl);
3635  $gui_class = $ui_plugin->getUIClassInstance();
3636  $resp = $gui_class->getHTML("Services/Utilities", "redirect", array("html" => $a_script));
3637  if ($resp["mode"] != ilUIHookPluginGUI::KEEP)
3638  {
3639  $a_script = $gui_class->modifyHTML($a_script, $resp);
3640  }
3641  }
3642  }
3643 
3644  header("Location: ".$a_script);
3645  exit();
3646  }
3647 
3656  public static function insertInstIntoID($a_value)
3657  {
3658  if (substr($a_value, 0, 4) == "il__")
3659  {
3660  $a_value = "il_".IL_INST_ID."_".substr($a_value, 4, strlen($a_value) - 4);
3661  }
3662 
3663  return $a_value;
3664  }
3665 
3676  public static function groupNameExists($a_group_name,$a_id = 0)
3677  {
3678  global $ilDB,$ilErr;
3679 
3680  if (empty($a_group_name))
3681  {
3682  $message = __METHOD__.": No groupname given!";
3683  $ilErr->raiseError($message,$ilErr->WARNING);
3684  }
3685 
3686  $clause = ($a_id) ? " AND obj_id != ".$ilDB->quote($a_id)." " : "";
3687 
3688  $q = "SELECT obj_id FROM object_data ".
3689  "WHERE title = ".$ilDB->quote($a_group_name, "text")." ".
3690  "AND type = ".$ilDB->quote("grp", "text").
3691  $clause;
3692 
3693  $r = $ilDB->query($q);
3694 
3695  if ($r->numRows())
3696  {
3697  return true;
3698  }
3699  else
3700  {
3701  return false;
3702  }
3703  }
3704 
3711  public static function getMemString()
3712  {
3713  $my_pid = getmypid();
3714  return ("MEMORY USAGE (% KB PID ): ".`ps -eo%mem,rss,pid | grep $my_pid`);
3715  }
3716 
3723  public static function isWindows()
3724  {
3725  if (strtolower(substr(php_uname(), 0, 3)) == "win")
3726  {
3727  return true;
3728  }
3729  return false;
3730  }
3731 
3732 
3733  public static function escapeShellArg($a_arg)
3734  {
3735  setlocale(LC_CTYPE, "UTF8", "en_US.UTF-8"); // fix for PHP escapeshellcmd bug. See: http://bugs.php.net/bug.php?id=45132
3736  // see also ilias bug 5630
3737  return escapeshellarg($a_arg);
3738  }
3739 
3749  public static function escapeShellCmd($a_arg)
3750  {
3751  if(ini_get('safe_mode') == 1)
3752  {
3753  return $a_arg;
3754  }
3755  setlocale(LC_CTYPE, "UTF8", "en_US.UTF-8"); // fix for PHP escapeshellcmd bug. See: http://bugs.php.net/bug.php?id=45132
3756  return escapeshellcmd($a_arg);
3757  }
3758 
3768  public static function execQuoted($cmd, $args = NULL)
3769  {
3770  global $ilLog;
3771 
3772  if(ilUtil::isWindows() && strpos($cmd, " ") !== false && substr($cmd, 0, 1) !== '"')
3773  {
3774  // cmd won't work without quotes
3775  $cmd = '"'.$cmd.'"';
3776  if($args)
3777  {
3778  // args are also quoted, workaround is to quote the whole command AGAIN
3779  // was fixed in php 5.2 (see php bug #25361)
3780  if (version_compare(phpversion(), "5.2", "<") && strpos($args, '"') !== false)
3781  {
3782  $cmd = '"'.$cmd." ".$args.'"';
3783  }
3784  // args are not quoted or php is fixed, just append
3785  else
3786  {
3787  $cmd .= " ".$args;
3788  }
3789  }
3790  }
3791  // nothing todo, just append args
3792  else if($args)
3793  {
3794  $cmd .= " ".$args;
3795  }
3796 //echo "<br>".$cmd; exit;
3797  exec($cmd, $arr);
3798 // $ilLog->write("ilUtil::execQuoted: ".$cmd.".");
3799  return $arr;
3800  }
3801 
3824  public static function excelTime($year = "", $month = "", $day = "", $hour = "", $minute = "", $second = "")
3825  {
3826  $starting_time = mktime(0, 0, 0, 1, 2, 1970);
3827  if (strcmp("$year$month$day$hour$minute$second", "") == 0)
3828  {
3829  $target_time = time();
3830  }
3831  else
3832  {
3833  if ($year < 1970)
3834  {
3835  return 0;
3836  }
3837  }
3838  $target_time = mktime($hour, $minute, $second, $month, $day, $year);
3839  $difference = $target_time - $starting_time;
3840  $days = (($difference - ($difference % 86400)) / 86400);
3841  $difference = $difference - ($days * 86400) + 3600;
3842  return ($days + 25570 + ($difference / 86400));
3843  }
3844 
3851  public static function renameExecutables($a_dir)
3852  {
3853  $def_arr = explode(",", SUFFIX_REPL_DEFAULT);
3854  foreach ($def_arr as $def)
3855  {
3856  ilUtil::rRenameSuffix($a_dir, trim($def), "sec");
3857  }
3858 
3859  $def_arr = explode(",", SUFFIX_REPL_ADDITIONAL);
3860  foreach ($def_arr as $def)
3861  {
3862  ilUtil::rRenameSuffix($a_dir, trim($def), "sec");
3863  }
3864  }
3865 
3878  public static function rRenameSuffix ($a_dir, $a_old_suffix, $a_new_suffix)
3879  {
3880  if ($a_dir == "/" || $a_dir == "" || is_int(strpos($a_dir, ".."))
3881  || trim($a_old_suffix) == "")
3882  {
3883  return false;
3884  }
3885 
3886  // check if argument is directory
3887  if (!@is_dir($a_dir))
3888  {
3889  return false;
3890  }
3891 
3892  // read a_dir
3893  $dir = opendir($a_dir);
3894 
3895  while($file = readdir($dir))
3896  {
3897  if ($file != "." and
3898  $file != "..")
3899  {
3900  // directories
3901  if (@is_dir($a_dir."/".$file))
3902  {
3903  ilUtil::rRenameSuffix($a_dir."/".$file, $a_old_suffix, $a_new_suffix);
3904  }
3905 
3906  // files
3907  if (@is_file($a_dir."/".$file))
3908  {
3909  // first check for files with trailing dot
3910  if(strrpos($file,'.') == (strlen($file) - 1))
3911  {
3912  rename($a_dir.'/'.$file,substr($a_dir.'/'.$file,0,-1));
3913  $file = substr($file,0,-1);
3914  }
3915 
3916  $path_info = pathinfo($a_dir."/".$file);
3917 
3918  if (strtolower($path_info["extension"]) ==
3919  strtolower($a_old_suffix))
3920  {
3921  $pos = strrpos($a_dir."/".$file, ".");
3922  $new_name = substr($a_dir."/".$file, 0, $pos).".".$a_new_suffix;
3923  rename($a_dir."/".$file, $new_name);
3924  }
3925  }
3926  }
3927  }
3928  return true;
3929  }
3930 
3931  public static function isAPICall () {
3932  return strpos($_SERVER["SCRIPT_FILENAME"],"api") !== false ||
3933  strpos($_SERVER["SCRIPT_FILENAME"],"dummy") !== false;
3934  }
3935 
3936  public static function KT_replaceParam($qstring, $paramName, $paramValue) {
3937  if (preg_match("/&" . $paramName . "=/", $qstring)) {
3938  return preg_replace("/&" . $paramName . "=[^&]+/", "&" . $paramName . "=" . urlencode($paramValue), $qstring);
3939  } else {
3940  return $qstring . "&" . $paramName . "=" . urlencode($paramValue);
3941  }
3942  }
3943 
3944  public static function replaceUrlParameterString ($url, $parametersArray) {
3945 
3946  foreach ($parametersArray as $paramName => $paramValue ) {
3947  $url = ilUtil::KT_replaceParam($url, $paramName, $paramValue);
3948  }
3949  return $url;
3950  }
3951 
3958  public static function generatePasswords ($a_number)
3959  {
3960  $ret = array();
3961  srand((double) microtime()*1000000);
3962 
3963  include_once('./Services/PrivacySecurity/classes/class.ilSecuritySettings.php');
3964  $security = ilSecuritySettings::_getInstance();
3965 
3966  for ($i=1; $i<=$a_number; $i++)
3967  {
3968  $min = ($security->getPasswordMinLength() > 0)
3969  ? $security->getPasswordMinLength()
3970  : 6;
3971  $max = ($security->getPasswordMaxLength() > 0)
3972  ? $security->getPasswordMaxLength()
3973  : 10;
3974  if ($min > $max)
3975  {
3976  $max = $max + 1;
3977  }
3978  $length = rand($min,$max);
3979  $next = rand(1,2);
3980  $vowels = "aeiou";
3981  $vowels_uc = strtoupper($vowels);
3982  $consonants = "bcdfghjklmnpqrstvwxyz";
3983  $consonants_uc = strtoupper($consonants);
3984  $numbers = "1234567890";
3985  $special = "_.+?#-*@!$%~";
3986  $pw = "";
3987 
3988  if($security->getPasswordNumberOfUppercaseChars() > 0)
3989  {
3990  for($j = 0; $j < $security->getPasswordNumberOfUppercaseChars(); $j++)
3991  {
3992  switch ($next)
3993  {
3994  case 1:
3995  $pw.= $consonants_uc[rand(0, strlen($consonants_uc) - 1)];
3996  $next = 2;
3997  break;
3998 
3999  case 2:
4000  $pw.= $vowels_uc[rand(0, strlen($vowels_uc) - 1)];
4001  $next = 1;
4002  break;
4003  }
4004  }
4005  }
4006 
4007  if($security->isPasswordCharsAndNumbersEnabled())
4008  {
4009  $pw.= $numbers[rand(0, strlen($numbers) - 1)];
4010  }
4011 
4012  if($security->isPasswordSpecialCharsEnabled())
4013  {
4014  $pw.= $special[rand(0, strlen($special) - 1)];
4015  }
4016 
4017  $num_lcase_chars = max($security->getPasswordNumberOfLowercaseChars(), $length - strlen($pw));
4018  for($j = 0; $j < $num_lcase_chars; $j++)
4019  {
4020  switch ($next)
4021  {
4022  case 1:
4023  $pw.= $consonants[rand(0, strlen($consonants) - 1)];
4024  $next = 2;
4025  break;
4026 
4027  case 2:
4028  $pw.= $vowels[rand(0, strlen($vowels) - 1)];
4029  $next = 1;
4030  break;
4031  }
4032  }
4033 
4034  $pw = str_shuffle($pw);
4035 
4036  $ret[] = $pw;
4037  }
4038  return $ret;
4039  }
4040 
4041  public static function removeTrailingPathSeparators($path)
4042  {
4043  $path = preg_replace("/[\/\\\]+$/", "", $path);
4044  return $path;
4045  }
4046 
4057  public static function array_php2js($data)
4058  {
4059  if (empty($data))
4060  {
4061  $data = array();
4062  }
4063 
4064  foreach($data as $k=>$datum)
4065  {
4066  if(is_null($datum)) $data[$k] = 'null';
4067  if(is_string($datum)) $data[$k] = "'" . $datum . "'";
4068  if(is_array($datum)) $data[$k] = array_php2js($datum);
4069  }
4070 
4071  return "[" . implode(', ', $data) . "]";
4072  }
4073 
4080  public static function virusHandling($a_file, $a_orig_name = "", $a_clean = true)
4081  {
4082  global $lng;
4083 
4084  if (IL_VIRUS_SCANNER != "None")
4085  {
4086  require_once("./Services/VirusScanner/classes/class.ilVirusScannerFactory.php");
4088  if (($vs_txt = $vs->scanFile($a_file, $a_orig_name)) != "")
4089  {
4090  if ($a_clean && (IL_VIRUS_CLEAN_COMMAND != ""))
4091  {
4092  $clean_txt = $vs->cleanFile($a_file, $a_orig_name);
4093  if ($vs->fileCleaned())
4094  {
4095  $vs_txt.= "<br />".$lng->txt("cleaned_file").
4096  "<br />".$clean_txt;
4097  $vs_txt.= "<br />".$lng->txt("repeat_scan");
4098  if (($vs2_txt = $vs->scanFile($a_file, $a_orig_name)) != "")
4099  {
4100  return array(false, nl2br($vs_txt)."<br />".$lng->txt("repeat_scan_failed").
4101  "<br />".nl2br($vs2_txt));
4102  }
4103  else
4104  {
4105  return array(true, nl2br($vs_txt)."<br />".$lng->txt("repeat_scan_succeded"));
4106  }
4107  }
4108  else
4109  {
4110  return array(false, nl2br($vs_txt)."<br />".$lng->txt("cleaning_failed"));
4111  }
4112  }
4113  else
4114  {
4115  return array(false, nl2br($vs_txt));
4116  }
4117  }
4118  }
4119 
4120  return array(true,"");
4121  }
4122 
4123 
4130  public static function moveUploadedFile($a_file, $a_name, $a_target, $a_raise_errors = true,
4131  $a_mode = "move_uploaded")
4132  {
4133  global $lng, $ilias;
4134 //echo "<br>ilUtli::moveuploadedFile($a_name)";
4135 
4136  if (!is_file($a_file))
4137  {
4138  if ($a_raise_errors)
4139  {
4140  $ilias->raiseError($lng->txt("upload_error_file_not_found"), $ilias->error_obj->MESSAGE);
4141  }
4142  else
4143  {
4144  ilUtil::sendFailure($lng->txt("upload_error_file_not_found"), true);
4145  }
4146  return false;
4147  }
4148 
4149  // virus handling
4150  $vir = ilUtil::virusHandling($a_file, $a_name);
4151  if (!$vir[0])
4152  {
4153  unlink($a_file);
4154  if ($a_raise_errors)
4155  {
4156  $ilias->raiseError($lng->txt("file_is_infected")."<br />".
4157  $vir[1],
4158  $ilias->error_obj->MESSAGE);
4159  }
4160  else
4161  {
4162  ilUtil::sendFailure($lng->txt("file_is_infected")."<br />".
4163  $vir[1], true);
4164  }
4165  return false;
4166  }
4167  else
4168  {
4169  if ($vir[1] != "")
4170  {
4171  ilUtil::sendInfo($vir[1], true);
4172  }
4173  switch ($a_mode)
4174  {
4175  case "rename":
4176  return rename($a_file, $a_target);
4177  break;
4178 
4179  case "copy":
4180  return copy($a_file, $a_target);
4181  break;
4182 
4183  default:
4184  return move_uploaded_file($a_file, $a_target);
4185  break;
4186  }
4187  }
4188  }
4189 
4190 
4197  public static function date_mysql2time($mysql_date_time) {
4198  list($datum, $uhrzeit) = explode (" ",$mysql_date_time);
4199  list($jahr, $monat, $tag) = explode("-", $datum);
4200  list($std, $min, $sec) = explode(":", $uhrzeit);
4201  return mktime ((int) $std, (int) $min, (int) $sec, (int) $monat, (int) $tag, (int) $jahr);
4202  }
4203 
4210  public static function now()
4211  {
4212  return date("Y-m-d H:i:s");
4213  }
4214 
4230  public static function &processCSVRow(&$row, $quoteAll = FALSE, $separator = ";", $outUTF8 = FALSE, $compatibleWithMSExcel = TRUE)
4231  {
4232  $resultarray = array();
4233  foreach ($row as $rowindex => $entry)
4234  {
4235  $surround = FALSE;
4236  if ($quoteAll)
4237  {
4238  $surround = TRUE;
4239  }
4240  if (strpos($entry, "\"") !== FALSE)
4241  {
4242  $entry = str_replace("\"", "\"\"", $entry);
4243  $surround = TRUE;
4244  }
4245  if (strpos($entry, $separator) !== FALSE)
4246  {
4247  $surround = TRUE;
4248  }
4249  if ($compatibleWithMSExcel)
4250  {
4251  // replace all CR LF with LF (for Excel for Windows compatibility
4252  $entry = str_replace(chr(13).chr(10), chr(10), $entry);
4253  }
4254  if ($surround)
4255  {
4256  if ($outUTF8)
4257  {
4258  $resultarray[$rowindex] = "\"" . $entry . "\"";
4259  }
4260  else
4261  {
4262  $resultarray[$rowindex] = utf8_decode("\"" . $entry . "\"");
4263  }
4264  }
4265  else
4266  {
4267  if ($outUTF8)
4268  {
4269  $resultarray[$rowindex] = $entry;
4270  }
4271  else
4272  {
4273  $resultarray[$rowindex] = utf8_decode($entry);
4274  }
4275  }
4276  }
4277  return $resultarray;
4278  }
4279 
4280  // validates a domain name (example: www.ilias.de)
4281  public static function isDN($a_str)
4282  {
4283  return(preg_match("/^[a-z]+([a-z0-9-]*[a-z0-9]+)?(\.([a-z]+([a-z0-9-]*[a-z0-9]+)?)+)*$/",$a_str));
4284  }
4285 
4286  // validates an IP address (example: 192.168.1.1)
4287  public static function isIPv4($a_str)
4288  {
4289  return(preg_match("/^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.".
4290  "(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/",$a_str));
4291  }
4292 
4293 
4322  public static function _getObjectsByOperations($a_obj_type,$a_operation,$a_usr_id = 0,$limit = 0)
4323  {
4324  global $ilDB,$rbacreview,$ilAccess,$ilUser,$ilias,$tree;
4325 
4326  if(!is_array($a_obj_type))
4327  {
4328  $where = "WHERE type = ".$ilDB->quote($a_obj_type, "text")." ";
4329  }
4330  else
4331  {
4332  $where = "WHERE ".$ilDB->in("type", $a_obj_type, false, "text")." ";
4333  }
4334 
4335  // limit number of results default is search result limit
4336  if(!$limit)
4337  {
4338  $limit = $ilias->getSetting('search_max_hits',100);
4339  }
4340  if($limit == -1)
4341  {
4342  $limit = 10000;
4343  }
4344 
4345  // default to logged in usr
4346  $a_usr_id = $a_usr_id ? $a_usr_id : $ilUser->getId();
4347  $a_roles = $rbacreview->assignedRoles($a_usr_id);
4348 
4349  // Since no rbac_pa entries are available for the system role. This function returns !all! ref_ids in the case the user
4350  // is assigned to the system role
4351  if($rbacreview->isAssigned($a_usr_id,SYSTEM_ROLE_ID))
4352  {
4353  $query = "SELECT ref_id FROM object_reference obr LEFT JOIN object_data obd ON obr.obj_id = obd.obj_id ".
4354  "LEFT JOIN tree ON obr.ref_id = tree.child ".
4355  $where.
4356  "AND tree = 1";
4357 
4358  $res = $ilDB->query($query);
4359  $counter = 0;
4360  while($row = $ilDB->fetchObject($res))
4361  {
4362  // Filter recovery folder
4363  if($tree->isGrandChild(RECOVERY_FOLDER_ID, $row->ref_id))
4364  {
4365  continue;
4366  }
4367 
4368  if($counter++ >= $limit)
4369  {
4370  break;
4371  }
4372 
4373  $ref_ids[] = $row->ref_id;
4374  }
4375  return $ref_ids ? $ref_ids : array();
4376  } // End Administrators
4377 
4378  // Check ownership if it is not asked for edit_permission or a create permission
4379  if($a_operation == 'edit_permissions' or strpos($a_operation,'create') !== false)
4380  {
4381  $check_owner = ") ";
4382  }
4383  else
4384  {
4385  $check_owner = "OR owner = ".$ilDB->quote($a_usr_id, "integer").") ";
4386  }
4387 
4388  $ops_ids = ilRbacReview::_getOperationIdsByName(array($a_operation));
4389  $ops_id = $ops_ids[0];
4390 
4391  $and = "AND ((".$ilDB->in("rol_id", $a_roles, false, "integer")." ";
4392 
4393  $query = "SELECT DISTINCT(obr.ref_id),obr.obj_id,type FROM object_reference obr ".
4394  "JOIN object_data obd ON obd.obj_id = obr.obj_id ".
4395  "LEFT JOIN rbac_pa ON obr.ref_id = rbac_pa.ref_id ".
4396  $where.
4397  $and.
4398  "AND (".$ilDB->like("ops_id", "text","%i:".$ops_id."%"). " ".
4399  "OR ".$ilDB->like("ops_id", "text", "%:\"".$ops_id."\";%").")) ".
4400  $check_owner;
4401 
4402  $res = $ilDB->query($query);
4403  $counter = 0;
4404  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
4405  {
4406  if($counter >= $limit)
4407  {
4408  break;
4409  }
4410 
4411  // Filter objects in recovery folder
4412  if($tree->isGrandChild(RECOVERY_FOLDER_ID, $row->ref_id))
4413  {
4414  continue;
4415  }
4416 
4417  // Check deleted, hierarchical access ...
4418  if($ilAccess->checkAccessOfUser($a_usr_id,$a_operation,'',$row->ref_id,$row->type,$row->obj_id))
4419  {
4420  $counter++;
4421  $ref_ids[] = $row->ref_id;
4422  }
4423  }
4424  return $ref_ids ? $ref_ids : array();
4425  }
4426 
4427 
4434  function includeMathjax($a_tpl = null)
4435  {
4436  global $tpl;
4437 
4438  if ($a_tpl == null)
4439  {
4440  $a_tpl = $tpl;
4441  }
4442 
4443  // - take care of html exports (-> see buildLatexImages)
4444  include_once "./Services/Administration/classes/class.ilSetting.php";
4445  $mathJaxSetting = new ilSetting("MathJax");
4446  $use_mathjax = $mathJaxSetting->get("enable");
4447  if ($use_mathjax)
4448  {
4449  $a_tpl->addJavaScript($mathJaxSetting->get("path_to_mathjax"));
4450  }
4451  }
4452 
4453 
4463  public static function insertLatexImages($a_text, $a_start = "\[tex\]", $a_end = "\[\/tex\]")
4464  {
4465  global $tpl, $lng, $ilUser;
4466 
4467  $cgi = URL_TO_LATEX;
4468 
4469  // - take care of html exports (-> see buildLatexImages)
4470  include_once "./Services/Administration/classes/class.ilSetting.php";
4471  $mathJaxSetting = new ilSetting("MathJax");
4472  $use_mathjax = $mathJaxSetting->get("enable");
4473  if ($use_mathjax)
4474  {
4475  $a_text = preg_replace("/\\\\([RZN])([^a-zA-Z]|<\/span>)/", "\\mathbb{"."$1"."}"."$2", $a_text);
4476  $tpl->addJavaScript($mathJaxSetting->get("path_to_mathjax"));
4477  }
4478 
4479  // this is a fix for bug5362
4480  $cpos = 0;
4481  $o_start = $a_start;
4482  $o_end = $a_end;
4483  $a_start = str_replace("\\", "", $a_start);
4484  $a_end = str_replace("\\", "", $a_end);
4485 
4486  while (is_int($spos = stripos($a_text, $a_start, $cpos))) // find next start
4487  {
4488  if (is_int ($epos = stripos($a_text, $a_end, $spos + 1)))
4489  {
4490  $tex = substr($a_text, $spos + strlen($a_start), $epos - $spos - strlen($a_start));
4491 
4492  // replace, if tags do not go across div borders
4493  if (!is_int(strpos($tex, "</div>")))
4494  {
4495  if (!$use_mathjax)
4496  {
4497  $a_text = substr($a_text, 0, $spos).
4498  "<img alt=\"".htmlentities($tex)."\" src=\"".$cgi."?".
4499  rawurlencode(str_replace('&amp;', '&', str_replace('&gt;', '>', str_replace('&lt;', '<', $tex))))."\" ".
4500  " />".
4501  substr($a_text, $epos + strlen($a_end));
4502  }
4503  else
4504  {
4505  $tex = $a_start.$tex.$a_end;
4506 
4507  switch ((int) $mathJaxSetting->get("limiter"))
4508  {
4509  case 1:
4510  $mj_start = "[tex]";
4511  $mj_end = "[/tex]";
4512  break;
4513 
4514  case 2:
4515  $mj_start = '<span class="math">';
4516  $mj_end = '</span>';
4517  break;
4518 
4519  default:
4520  $mj_start = "\(";
4521  $mj_end = "\)";
4522  break;
4523  }
4524 
4525  $replacement =
4526  preg_replace('/' . $o_start . '(.*?)' . $o_end . '/ie',
4527  "'".$mj_start."' . preg_replace('/[\\\\\\\\\\]{2}/', '\\cr', str_replace('<', '&lt;', str_replace('<br/>', '', str_replace('<br />', '', str_replace('<br>', '', '$1'))))) . '".$mj_end."'", $tex);
4528  // added special handling for \\ -> \cr, < -> $lt; and removal of <br/> tags in jsMath expressions, H. Schottmüller, 2007-09-09
4529  $a_text = substr($a_text, 0, $spos).
4530  $replacement.
4531  substr($a_text, $epos + strlen($a_end));
4532  }
4533  }
4534  }
4535  $cpos = $spos + 1;
4536  }
4537 
4538  $result_text = $a_text;
4539 
4540  return $result_text;
4541  }
4542 
4552  public static function buildLatexImages($a_text, $a_dir)
4553  {
4554  $result_text = $a_text;
4555 
4556  $start = "\[tex\]";
4557  $end = "\[\/tex\]";
4558 
4559  $cgi = URL_TO_LATEX;
4560 
4561  if ($cgi != "")
4562  {
4563  while (preg_match('/' . $start . '(.*?)' . $end . '/ie', $result_text, $found))
4564  {
4565  $cnt = (int) $GLOBALS["teximgcnt"]++;
4566  // get image from cgi and write it to file
4567  $fpr = @fopen($cgi."?".rawurlencode($found[1]), "r");
4568  $lcnt = 0;
4569  if ($fpr)
4570  {
4571  while(!feof($fpr))
4572  {
4573  $buf = fread($fpr, 1024);
4574  if ($lcnt == 0)
4575  {
4576  if (is_int(strpos(strtoupper(substr($buf, 0, 5)), "GIF")))
4577  {
4578  $suffix = "gif";
4579  }
4580  else
4581  {
4582  $suffix = "png";
4583  }
4584  $fpw = fopen($a_dir."/teximg/img".$cnt.".".$suffix, "w");
4585  }
4586  $lcnt++;
4587  fwrite($fpw, $buf);
4588  }
4589  fclose($fpw);
4590  fclose($fpr);
4591  }
4592 
4593  // replace tex-tag
4594  $img_str = "./teximg/img".$cnt.".".$suffix;
4595  $result_text = str_replace($found[0],
4596  '<img alt="'.$found[1].'" src="'.$img_str.'" />', $result_text);
4597  }
4598  }
4599 
4600  return $result_text;
4601  }
4602 
4611  public static function prepareTextareaOutput($txt_output, $prepare_for_latex_output = FALSE)
4612  {
4613  $result = $txt_output;
4614  $is_html = self::isHTML($result);
4615 
4616  if ($prepare_for_latex_output)
4617  {
4618  $result = ilUtil::insertLatexImages($result, "<span class\=\"latex\">", "<\/span>");
4619  $result = ilUtil::insertLatexImages($result, "\[tex\]", "\[\/tex\]");
4620  }
4621 
4622  // removed: did not work with magic_quotes_gpc = On
4623  if (!$is_html)
4624  {
4625  // if the string does not contain HTML code, replace the newlines with HTML line breaks
4626  $result = preg_replace("/[\n]/", "<br />", $result);
4627  }
4628  else
4629  {
4630  // patch for problems with the <pre> tags in tinyMCE
4631  if (preg_match_all("/(<pre>.*?<\/pre>)/ims", $result, $matches))
4632  {
4633  foreach ($matches[0] as $found)
4634  {
4635  $replacement = "";
4636  if (strpos("\n", $found) === FALSE)
4637  {
4638  $replacement = "\n";
4639  }
4640  $removed = preg_replace("/<br\s*?\/>/ims", $replacement, $found);
4641  $result = str_replace($found, $removed, $result);
4642  }
4643  }
4644  }
4645  if ($prepare_for_latex_output)
4646  {
4647  // replace special characters to prevent problems with the ILIAS template system
4648  // eg. if someone uses {1} as an answer, nothing will be shown without the replacement
4649  $result = str_replace("{", "&#123;", $result);
4650  $result = str_replace("}", "&#125;", $result);
4651  $result = str_replace("\\", "&#92;", $result);
4652  }
4653 
4654  return $result;
4655  }
4656 
4665  public static function isHTML($a_text)
4666  {
4667  if( preg_match("/<[^>]*?>/", $a_text) )
4668  {
4669  return true;
4670  }
4671 
4672  return false;
4673  }
4674 
4683  public static function int2array ($seconds, $periods = null)
4684  {
4685  // Define time periods
4686  if (!is_array($periods))
4687  {
4688  $periods = array (
4689  'years' => 31536000,
4690  'months' => 2592000,
4691  'days' => 86400,
4692  'hours' => 3600,
4693  'minutes' => 60,
4694  'seconds' => 1
4695  );
4696  }
4697 
4698  // Loop
4699  $seconds = (float) $seconds;
4700  foreach ($periods as $period => $value)
4701  {
4702  $count = floor($seconds / $value);
4703 
4704  if ($count == 0)
4705  {
4706  continue;
4707  }
4708 
4709  $values[$period] = $count;
4710  $seconds = $seconds % $value;
4711  }
4712  // Return
4713  if (empty($values))
4714  {
4715  $values = null;
4716  }
4717 
4718  return $values;
4719  }
4720 
4729  public static function timearray2string ($duration)
4730  {
4731  global $lng;
4732 
4733  if (!is_array($duration))
4734  {
4735  return false;
4736  }
4737 
4738  foreach ($duration as $key => $value) {
4739 
4740  // Plural
4741  if ($value > 1)
4742  {
4743  $segment_name = $key;
4744  $segment_name = $lng->txt($segment_name);
4745  $segment = $value . ' ' . $segment_name;
4746  }
4747  else
4748  {
4749  $segment_name = substr($key, 0, -1);
4750  $segment_name = $lng->txt($segment_name);
4751  $segment = $value . ' ' . $segment_name;
4752  }
4753 
4754  $array[] = $segment;
4755  }
4756  $len = count($array);
4757 
4758  if ($len>3)
4759  {
4760  $array=array_slice($array,0,(3-$len));
4761  }
4762 
4763  $str = implode(', ', $array);
4764 
4765  return $str;
4766  }
4767 
4768  public static function getFileSizeInfo()
4769  {
4770  global $lng;
4771 
4772  // get the value for the maximal uploadable filesize from the php.ini (if available)
4773  $umf=get_cfg_var("upload_max_filesize");
4774  // get the value for the maximal post data from the php.ini (if available)
4775  $pms=get_cfg_var("post_max_size");
4776 
4777  // use the smaller one as limit
4778  $max_filesize=min($umf, $pms);
4779  if (!$max_filesize) $max_filesize=max($umf, $pms);
4780 
4781  return $lng->txt("file_notice")." $max_filesize.";
4782  }
4783 
4792  public static function __extractRefId($role_title)
4793  {
4794 
4795  $test_str = explode('_',$role_title);
4796 
4797  if ($test_str[0] == 'il')
4798  {
4799  $test2 = (int) $test_str[3];
4800  return is_numeric ($test2) ? (int) $test2 : false;
4801  }
4802  return false;
4803  }
4804 
4815  public static function __extractId($ilias_id, $inst_id)
4816  {
4817 
4818  $test_str = explode('_',$ilias_id);
4819 
4820  if ($test_str[0] == 'il' && $test_str[1] == $inst_id && count($test_str) == 4)
4821  {
4822  $test2 = (int) $test_str[3];
4823  return is_numeric ($test2) ? (int) $test2 : false;
4824  }
4825  return false;
4826  }
4827 
4842  public static function _sortIds($a_ids,$a_table,$a_field,$a_id_name)
4843  {
4844  global $ilDB;
4845 
4846  if(!$a_ids)
4847  {
4848  return array();
4849  }
4850 
4851  // use database to sort user array
4852  $where = "WHERE ".$a_id_name." IN (";
4853  $where .= implode(",", ilUtil::quoteArray($a_ids));
4854  $where .= ") ";
4855 
4856  $query = "SELECT ".$a_id_name." FROM ".$a_table." ".
4857  $where.
4858  "ORDER BY ".$a_field;
4859 
4860  $res = $ilDB->query($query);
4861  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
4862  {
4863  $ids[] = $row->$a_id_name;
4864  }
4865  return $ids ? $ids : array();
4866  }
4867 
4877  public static function getMySQLTimestamp($a_ts)
4878  {
4879  global $ilDB;
4880 
4881  return $a_ts;
4882  }
4883 
4890  public static function quoteArray($a_array)
4891  {
4892  global $ilDB;
4893 
4894 
4895  if(!is_array($a_array) or !count($a_array))
4896  {
4897  return array("''");
4898  }
4899 
4900  foreach($a_array as $k => $item)
4901  {
4902  $a_array[$k] = $ilDB->quote($item);
4903  }
4904 
4905  return $a_array;
4906  }
4907 
4916  public static function sendInfo($a_info = "",$a_keep = false)
4917  {
4918  global $tpl;
4919  $tpl->setMessage("info", $a_info, $a_keep);
4920  }
4921 
4930  public static function sendFailure($a_info = "",$a_keep = false)
4931  {
4932  global $tpl;
4933  $tpl->setMessage("failure", $a_info, $a_keep);
4934  }
4935 
4942  public static function sendQuestion($a_info = "",$a_keep = false)
4943  {
4944  global $tpl;
4945  $tpl->setMessage("question", $a_info, $a_keep);
4946  }
4947 
4956  public static function sendSuccess($a_info = "",$a_keep = false)
4957  {
4958  global $tpl;
4959  $tpl->setMessage("success", $a_info, $a_keep);
4960  }
4961 
4962  public static function infoPanel($a_keep = true)
4963  {
4964  global $tpl,$ilias,$lng;
4965 
4966  if (!empty($_SESSION["infopanel"]) and is_array($_SESSION["infopanel"]))
4967  {
4968  $tpl->addBlockFile("INFOPANEL", "infopanel", "tpl.infopanel.html",
4969  "Services/Utilities");
4970  $tpl->setCurrentBlock("infopanel");
4971 
4972  if (!empty($_SESSION["infopanel"]["text"]))
4973  {
4974  $link = "<a href=\"".$dir.$_SESSION["infopanel"]["link"]."\" target=\"".
4975  ilFrameTargetInfo::_getFrame("MainContent").
4976  "\">";
4977  $link .= $lng->txt($_SESSION["infopanel"]["text"]);
4978  $link .= "</a>";
4979  }
4980 
4981  // deactivated
4982  if (!empty($_SESSION["infopanel"]["img"]))
4983  {
4984  $link .= "<td><a href=\"".$_SESSION["infopanel"]["link"]."\" target=\"".
4985  ilFrameTargetInfo::_getFrame("MainContent").
4986  "\">";
4987  $link .= "<img src=\"".$ilias->tplPath.$ilias->account->prefs["skin"]."/images/".
4988  $_SESSION["infopanel"]["img"]."\" border=\"0\" vspace=\"0\"/>";
4989  $link .= "</a></td>";
4990  }
4991 
4992  $tpl->setVariable("INFO_ICONS",$link);
4993  $tpl->parseCurrentBlock();
4994  }
4995 
4996  //if (!$a_keep)
4997  //{
4998  ilSession::clear("infopanel");
4999  //}
5000  }
5001 
5002 
5011  public static function dirsize($directory)
5012  {
5013  $size = 0;
5014  if (!is_dir($directory))
5015  {
5016  // BEGIN DiskQuota Suppress PHP warning when attempting to determine
5017  // dirsize of non-existing directory
5018  $size = @filesize($directory);
5019  // END DiskQuota Suppress PHP warning.
5020  return ($size === false) ? -1 : $size;
5021  }
5022  if ($DIR = opendir($directory))
5023  {
5024  while (($dirfile = readdir($DIR)) !== false)
5025  {
5026  if (is_link($directory . DIRECTORY_SEPARATOR . $dirfile) || $dirfile == '.' || $dirfile == '..')
5027  continue;
5028  if (is_file($directory . DIRECTORY_SEPARATOR . $dirfile))
5029  $size += filesize($directory . DIRECTORY_SEPARATOR . $dirfile);
5030  else if (is_dir($directory . DIRECTORY_SEPARATOR . $dirfile))
5031  {
5032  // BEGIN DiskQuota: dirsize is not a global function anymore
5033  $dirSize = ilUtil::dirsize($directory . DIRECTORY_SEPARATOR . $dirfile);
5034  // END DiskQuota: dirsize is not a global function anymore
5035  if ($dirSize >= 0)
5036  $size += $dirSize;
5037  else return -1;
5038  }
5039  }
5040  closedir($DIR);
5041  }
5042  return $size;
5043  }
5044 
5045  public static function randomhash()
5046  {
5047  return md5(rand(1,9999999) + str_replace(" ", "", (string) microtime()));
5048  }
5049 
5050  public static function setCookie($a_cookie_name,$a_cookie_value = '', $a_also_set_super_global = true, $a_set_cookie_invalid = false)
5051  {
5052  /*
5053  if(!(bool)$a_set_cookie_invalid) $expire = IL_COOKIE_EXPIRE;
5054  else $expire = time() - (365*24*60*60);
5055  */
5056  // Temporary fix for feed.php
5057  if(!(bool)$a_set_cookie_invalid) $expire = 0;
5058  else $expire = time() - (365*24*60*60);
5059 
5060  // setcookie() supports 5th parameter
5061  // only for php version 5.2.0 and above
5062  if( version_compare(PHP_VERSION, '5.2.0', '>=') )
5063  {
5064  // PHP version >= 5.2.0
5065  setcookie( $a_cookie_name, $a_cookie_value, $expire,
5066  IL_COOKIE_PATH, IL_COOKIE_DOMAIN, IL_COOKIE_SECURE, IL_COOKIE_HTTPONLY
5067  );
5068  }
5069  else
5070  {
5071  // PHP version < 5.2.0
5072  setcookie( $a_cookie_name, $a_cookie_value, $expire,
5073  IL_COOKIE_PATH, IL_COOKIE_DOMAIN, IL_COOKIE_SECURE
5074  );
5075  }
5076 
5077  if((bool)$a_also_set_super_global) $_COOKIE[$a_cookie_name] = $a_cookie_value;
5078  }
5079 
5080  public static function _sanitizeFilemame($a_filename)
5081  {
5082  return strip_tags(self::stripSlashes($a_filename));
5083  }
5084 
5085  public static function _getHttpPath()
5086  {
5087  global $ilIliasIniFile;
5088 
5089  if($_SERVER['SHELL'] || php_sapi_name() == 'cli' ||
5090  // fallback for windows systems, useful in crons
5091  (class_exists("ilContext") && !ilContext::usesHTTP()))
5092  {
5093  return $ilIliasIniFile->readVariable('server', 'http_path');
5094  }
5095  else
5096  {
5097  return ILIAS_HTTP_PATH;
5098  }
5099  }
5100 
5106  public static function printBacktrace($a_limit = 0)
5107  {
5108  $bt = debug_backtrace();
5109  $cnt = 0;
5110  foreach ($bt as $t)
5111  {
5112  if ($cnt != 0 && ($a_limit == 0 || $cnt <= $a_limit))
5113  {
5114  echo "<br>".$t["file"].", ".$t["function"]." [".$t["line"]."]";
5115  }
5116  $cnt++;
5117  }
5118  echo "<br>";
5119  }
5120 
5135  public static function parseImportId($a_import_id)
5136  {
5137  $exploded = explode('_'.$a_import_id);
5138 
5139  $parsed['orig'] = $a_import_id;
5140  if($exploded[0] == 'il')
5141  {
5142  $parsed['prefix'] = $exploded[0];
5143  }
5144  if(is_numeric($exploded[1]))
5145  {
5146  $parsed['inst_id'] = (int) $exploded[1];
5147  }
5148  $parsed['type'] = $exploded[2];
5149 
5150  if(is_numeric($exploded[3]))
5151  {
5152  $parsed['id'] = (int) $exploded[3];
5153  }
5154  return $parsed;
5155  }
5156 
5163  public static function unserializeSession($data)
5164  {
5165  $vars = preg_split(
5166  '/([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff^|]*)\|/',
5167  $data,
5168  -1,
5169  PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE
5170  );
5171 
5172  $result = array();
5173 
5174  for($i = 0; $vars[$i]; $i++)
5175  {
5176  $result[$vars[$i++]] = unserialize($vars[$i]);
5177  }
5178 
5179  return $result;
5180  }
5181 
5182 
5193  function rangeDownload($file) {
5194 
5195  $fp = @fopen($file, 'rb');
5196 
5197  $size = filesize($file); // File size
5198  $length = $size; // Content length
5199  $start = 0; // Start byte
5200  $end = $size - 1; // End byte
5201  // Now that we've gotten so far without errors we send the accept range header
5202  /* At the moment we only support single ranges.
5203  * Multiple ranges requires some more work to ensure it works correctly
5204  * and comply with the spesifications: http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.2
5205  *
5206  * Multirange support annouces itself with:
5207  * header('Accept-Ranges: bytes');
5208  *
5209  * Multirange content must be sent with multipart/byteranges mediatype,
5210  * (mediatype = mimetype)
5211  * as well as a boundry header to indicate the various chunks of data.
5212  */
5213  header("Accept-Ranges: 0-$length");
5214  // header('Accept-Ranges: bytes');
5215  // multipart/byteranges
5216  // http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.2
5217  if (isset($_SERVER['HTTP_RANGE'])) {
5218 
5219  $c_start = $start;
5220  $c_end = $end;
5221  // Extract the range string
5222  list(, $range) = explode('=', $_SERVER['HTTP_RANGE'], 2);
5223  // Make sure the client hasn't sent us a multibyte range
5224  if (strpos($range, ',') !== false) {
5225 
5226  // (?) Shoud this be issued here, or should the first
5227  // range be used? Or should the header be ignored and
5228  // we output the whole content?
5229  header('HTTP/1.1 416 Requested Range Not Satisfiable');
5230  header("Content-Range: bytes $start-$end/$size");
5231  // (?) Echo some info to the client?
5232  exit;
5233  }
5234  // If the range starts with an '-' we start from the beginning
5235  // If not, we forward the file pointer
5236  // And make sure to get the end byte if spesified
5237  if ($range == '-') {
5238 
5239  // The n-number of the last bytes is requested
5240  $c_start = $size - substr($range, 1);
5241  }
5242  else {
5243 
5244  $range = explode('-', $range);
5245  $c_start = $range[0];
5246  $c_end = (isset($range[1]) && is_numeric($range[1])) ? $range[1] : $size;
5247  }
5248  /* Check the range and make sure it's treated according to the specs.
5249  * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
5250  */
5251  // End bytes can not be larger than $end.
5252  $c_end = ($c_end > $end) ? $end : $c_end;
5253  // Validate the requested range and return an error if it's not correct.
5254  if ($c_start > $c_end || $c_start > $size - 1 || $c_end >= $size) {
5255 
5256  header('HTTP/1.1 416 Requested Range Not Satisfiable');
5257  header("Content-Range: bytes $start-$end/$size");
5258  // (?) Echo some info to the client?
5259  exit;
5260  }
5261  $start = $c_start;
5262  $end = $c_end;
5263  $length = $end - $start + 1; // Calculate new content length
5264  fseek($fp, $start);
5265  header('HTTP/1.1 206 Partial Content');
5266  }
5267  // Notify the client the byte range we'll be outputting
5268  header("Content-Range: bytes $start-$end/$size");
5269  header("Content-Length: $length");
5270 
5271  // Start buffered download
5272  $buffer = 1024 * 8;
5273  while(!feof($fp) && ($p = ftell($fp)) <= $end) {
5274 
5275  if ($p + $buffer > $end) {
5276 
5277  // In case we're only outputtin a chunk, make sure we don't
5278  // read past the length
5279  $buffer = $end - $p + 1;
5280  }
5281  set_time_limit(0); // Reset time limit for big files
5282  echo fread($fp, $buffer);
5283  flush(); // Free up memory. Otherwise large files will trigger PHP's memory limit.
5284  }
5285 
5286  fclose($fp);
5287 
5288  }
5289 
5290 
5291 } // END class.ilUtil
5292 
5293 
5294 ?>