ILIAS  Release_4_2_x_branch Revision 61807
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.ilCtrl.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (c) 1998-2009 ILIAS open source, Extended GPL, see docs/LICENSE */
3 
11 class ilCtrl
12 {
13  const IL_RTOKEN_NAME = 'rtoken';
14 
16  var $forward; // forward array
17  var $parent; // parent array (reverse forward)
18  var $save_parameter; // save parameter array
19  var $return; // return commmands
20  var $call_hist = array(); // calling history
21  var $debug = array();
22  var $calls = array();
23  var $rtoken = false;
24 
28  function ilCtrl()
29  {
30  global $ilBench;
31 
32  $this->bench =& $ilBench;
33 
34  // initialisation
35  $this->init();
36 
37  // this information should go to xml files one day
38  $this->stored_trees = array
39  ("ilrepositorygui", "ilpersonaldesktopgui",
40  "illmpresentationgui", "illmeditorgui",
41  "iladministrationgui");
42  }
43 
49  function debug($str)
50  {
51  $this->debug[] = $str;
52  }
53 
59  function getDebug()
60  {
61  return $this->debug;
62  }
63 
67  function init()
68  {
69  $this->transit = array();
70  $this->forward = array(); // forward array
71  $this->forwards = array(); // forward array
72  $this->parent = array(); // parent array (reverse forward)
73  $this->save_parameter = array(); // save parameter array
74  $this->parameter = array(); // save parameter array
75  $this->return = ""; // return commmands
76  $this->location = array();
77  $this->tab = array();
78  $this->current_node = 0;
79  $this->module_dir = "";
80  $this->service_dir = "";
81  $this->call_node = array();
82  $this->root_class = "";
83  }
84 
91  function callBaseClass()
92  {
93  global $ilDB;
94 
95  $baseClass = strtolower($_GET["baseClass"]);
96 
97  // get class information
98  $mc_set = $ilDB->query("SELECT * FROM module_class WHERE LOWER(class) = ".
99  $ilDB->quote($baseClass, "text"));
100  $mc_rec = $ilDB->fetchAssoc($mc_set);
101  $module = $mc_rec["module"];
102  $class = $mc_rec["class"];
103  $class_dir = $mc_rec["dir"];
104 
105  if ($module != "")
106  {
107  $m_set = $ilDB->query("SELECT * FROM il_component WHERE name = ".
108  $ilDB->quote($module, "text"));
109  $m_rec = $ilDB->fetchAssoc($m_set);
110  $this->module_dir = $m_rec["type"]."/".$m_rec["name"];
111  include_once $this->module_dir."/".$class_dir."/class.".$class.".php";
112  }
113  else // check whether class belongs to a service
114  {
115  $mc_set = $ilDB->query("SELECT * FROM service_class WHERE LOWER(class) = ".
116  $ilDB->quote($baseClass, "text"));
117  $mc_rec = $ilDB->fetchAssoc($mc_set);
118 
119  $service = $mc_rec["service"];
120  $class = $mc_rec["class"];
121  $class_dir = $mc_rec["dir"];
122 
123  if ($service == "")
124  {
125  echo "Could not find entry in modules.xml or services.xml for ".
126  $baseClass." <br/>".str_replace("&", "<br />&", htmlentities($_SERVER["REQUEST_URI"]));
127  exit;
128  }
129 
130  // get service information
131  $m_set = $ilDB->query("SELECT * FROM il_component WHERE name = ".
132  $ilDB->quote($service, "text"));
133  $m_rec = $ilDB->fetchAssoc($m_set);
134  $this->service_dir = $m_rec["type"]."/".$m_rec["name"];
135 
136  include_once $this->service_dir."/".$class_dir."/class.".$class.".php";;
137  }
138 
139  // forward processing to base class
140  $this->getCallStructure(strtolower($baseClass));
141  $base_class_gui =& new $class();
142  $this->forwardCommand($base_class_gui);
143  }
144 
148  function getModuleDir()
149  {
150  return $this->module_dir;
151  }
152 
162  function &forwardCommand(&$a_gui_object)
163  {
164  $class = strtolower(get_class($a_gui_object));
165 
166  $nr = $this->getNodeIdForTargetClass($this->current_node, $class);
167  if ($nr != "")
168  {
169  $current_node = $this->current_node;
170 
171  $this->current_node = $nr;
172 
173  // always populate the call history
174  // it will only be displayed in DEVMODE but is needed for UI plugins, too
175  $this->call_hist[] = array("class" => get_class($a_gui_object),
176  "mode" => "execComm", "cmd" => $this->getCmd());
177 
178 //echo "<br>class:".get_class($a_gui_object).":";
179  $html = $a_gui_object->executeCommand();
180 
181  // reset current node
182  $this->current_node = $current_node;
183 
184  return $html;
185 
186  }
187  echo "ERROR: Can't forward to class $class."; exit;
188  }
189 
197  function &getHTML(&$a_gui_object)
198  {
199  $class = strtolower(get_class($a_gui_object));
200 
201  $nr = $this->getNodeIdForTargetClass($this->current_node, $class);
202  if ($nr != "")
203  {
204  $current_node = $this->current_node;
205 
206  // set current node to new gui class
207  $this->current_node = $nr;
208 
209  // always populate the call history
210  // it will only be displayed in DEVMODE but is needed for UI plugins, too
211  $this->call_hist[] = array("class" => get_class($a_gui_object),
212  "mode" => "getHtml", "cmd" => $this->getCmd());
213 
214  // get block
215  $html = $a_gui_object->getHTML();
216 
217  // reset current node
218  $this->current_node = $current_node;
219 
220  // return block
221  return $html;
222  }
223  echo "ERROR: Can't getHTML from class $class."; exit;
224  }
225 
235  function setContext($a_obj_id, $a_obj_type, $a_sub_obj_id = 0, $a_sub_obj_type = "")
236  {
237  $this->context_obj_id = $a_obj_id;
238  $this->context_obj_type = $a_obj_type;
239  $this->context_sub_obj_id = $a_sub_obj_id;
240  $this->context_sub_obj_type = $a_sub_obj_type;
241  }
242 
248  public function getContextObjId()
249  {
250  return $this->context_obj_id;
251  }
252 
258  public function getContextObjType()
259  {
260  return $this->context_obj_type;
261  }
262 
268  public function getContextSubObjId()
269  {
270  return $this->context_sub_obj_id;
271  }
272 
278  public function getContextSubObjType()
279  {
280  return $this->context_sub_obj_type;
281  }
282 
301  function getNodeIdForTargetClass($a_par_node, $a_class, $a_check = false)
302  {
303  $class = strtolower($a_class);
304  $this->readClassInfo($class);
305 
306  if ($a_par_node === 0 || $a_par_node == "")
307  {
308  return $this->getCidForClass($class);
309  }
310 
311 //return parent::getNodeIdForTargetClass($a_par_node, $a_class);
312  $this->readNodeInfo($a_par_node);
313 
314  $node_cid = $this->getCurrentCidOfNode($a_par_node);
315 
316  // target class is class of current node id
317  if ($class == $this->getClassForCid($node_cid))
318  {
319  return $a_par_node;
320  }
321 
322  // target class is child of current node id
323  if (isset($this->calls[$this->getClassForCid($node_cid)]) &&
324  is_array($this->calls[$this->getClassForCid($node_cid)]) &&
325  in_array($a_class, $this->calls[$this->getClassForCid($node_cid)]))
326  {
327  return $a_par_node.":".$this->getCidForClass($class);
328  }
329 
330  // target class is sibling
331  $par_cid = $this->getParentCidOfNode($a_par_node);
332  if ($par_cid != "")
333  {
334  if (is_array($this->calls[$this->getClassForCid($par_cid)]) &&
335  in_array($a_class, $this->calls[$this->getClassForCid($par_cid)]))
336  {
337  return $this->removeLastCid($a_par_node).":".$this->getCidForClass($class);;
338  }
339  }
340 
341  // target class is parent
342  $temp_node = $this->removeLastCid($a_par_node);
343  while($temp_node != "")
344  {
345  $temp_cid = $this->getCurrentCidOfNode($temp_node);
346  if ($this->getClassForCid($temp_cid) == $a_class)
347  {
348  return $temp_node;
349  }
350  $temp_node = $this->removeLastCid($temp_node);
351  }
352 
353  if ($a_check)
354  {
355  return false;
356  }
357 
358  // Please do NOT change these lines.
359  // Developers must be aware, if they use classes unknown to the controller
360  // otherwise certain problem will be extremely hard to track down...
361  echo "ERROR: Can't find target class $a_class for node $a_par_node ".
362  "(".$this->cid_class[$this->getParentCidOfNode($a_par_node)].").<br>";
363  error_log( "ERROR: Can't find target class $a_class for node $a_par_node ".
364  "(".$this->cid_class[$this->getParentCidOfNode($a_par_node)].")");
365 
366  if (DEVMODE == 1)
367  {
369  }
370 
371  exit;
372  }
373 
380  function checkTargetClass($a_class)
381  {
382  if (!is_array($a_class))
383  {
384  $a_class = array($a_class);
385  }
386 
387  $nr = $this->current_node;
388  foreach ($a_class as $class)
389  {
390  $class = strtolower($class);
391 
392  if (!$this->getCidForClass($class, true))
393  {
394  return false;
395  }
396 
397  $nr = $this->getNodeIdForTargetClass($nr, $class, true);
398  if ($nr === false)
399  {
400  return false;
401  }
402  }
403  return true;
404  }
405 
411  function getCmdNode()
412  {
413  return $_GET["cmdNode"];
414  }
415 
423  function addLocation($a_title, $a_link, $a_target = "", $a_ref_id = 0)
424  {
425  $this->location[] = array("title" => $a_title,
426  "link" => $a_link, "target" => $a_target, "ref_id" => $a_ref_id);
427  }
428 
434  function getLocations()
435  {
436  return $this->location;
437  }
438 
447  function addTab($a_lang_var, $a_link, $a_cmd, $a_class)
448  {
449  $a_class = strtolower($a_class);
450 
451  $this->tab[] = array("lang_var" => $a_lang_var,
452  "link" => $a_link, "cmd" => $a_cmd, "class" => $a_class);
453  }
454 
460  function getTabs()
461  {
462  return $this->tab;
463  }
464 
471  function getCallHistory()
472  {
473  return $this->call_hist;
474  }
475 
492  function getCallStructure($a_class)
493  {
494  $this->readClassInfo($a_class);
495  }
496 
501 /* function storeCommonStructures()
502  {
503  global $ilDB;
504 
505  $ilDB->manipulate("DELETE FROM ctrl_structure");
506 
507  foreach ($this->stored_trees as $root_gui_class)
508  {
509  $this->call_node = array();
510  $this->forward = array();
511  $this->parent = array();
512  $this->readCallStructure($root_gui_class);
513  $ilDB->insert("ctrl_structure", array(
514  "root_class" => array("text", $root_gui_class),
515  "call_node" => array("text", serialize($this->call_node)),
516  "forward" => array("text", serialize($this->forward)),
517  "parent" => array("clob", serialize($this->parent))));
518  }
519  }
520 */
521 
525  function readCallStructure($a_class, $a_nr = 0, $a_parent = 0)
526  {
527  global $ilDB;
528 
529  $a_class = strtolower($a_class);
530 
531  $a_nr++;
532 
533  // determine call node structure
534  $this->call_node[$a_nr] = array("class" => $a_class, "parent" => $a_parent);
535 
536 //echo "<br>nr:$a_nr:class:$a_class:parent:$a_parent:";
537  $call_set = $ilDB->query("SELECT * FROM ctrl_calls WHERE parent = ".
538  $ilDB->quote(strtolower($a_class), "text").
539  " ORDER BY child", array("text"));
540  $a_parent = $a_nr;
541  while ($call_rec = $ilDB->fetchAssoc($call_set))
542  {
543  $a_nr = $this->readCallStructure($call_rec["child"], $a_nr, $a_parent);
544  $forw[] = $call_rec["child"];
545  }
546 
547  // determin forward and parent array
548  $this->forwards($a_class, $forw);
549 //echo "<br>forwards:".$a_class."<br>"; var_dump($forw);
550 
551  // determine root class
552  $this->root_class = $a_class;
553  return $a_nr;
554  }
555 
556 
563  private function forwards($a_from_class, $a_to_class)
564  {
565  $a_from_class = strtolower($a_from_class);
566 
567  if (is_array($a_to_class))
568  {
569  foreach($a_to_class as $to_class)
570  {
571  if ($a_from_class != "" && $to_class != "")
572  {
573  if (!is_array($this->forward[$a_from_class]) || !in_array(strtolower($to_class), $this->forward[$a_from_class]))
574  {
575  $this->forward[$a_from_class][] = strtolower($to_class);
576  }
577  if (!is_array($this->parent[strtolower($to_class)]) || !in_array($a_from_class, $this->parent[strtolower($to_class)]))
578  {
579  $this->parent[strtolower($to_class)][] = $a_from_class;
580  }
581  }
582  }
583  }
584  else
585  {
586  $to_class = $a_to_class;
587  if ($a_from_class != "" && $to_class != "")
588  {
589  if (!is_array($this->forward[$a_from_class]) || !in_array(strtolower($to_class), $this->forward[$a_from_class]))
590  {
591  $this->forward[$a_from_class][] = strtolower($to_class);
592  }
593  if (!is_array($this->parent[strtolower($to_class)]) || !in_array($a_from_class, $this->parent[strtolower($to_class)]))
594  {
595  $this->parent[strtolower($to_class)][] = $a_from_class;
596  }
597  }
598  }
599  }
600 
601 
621  public function saveParameter(&$a_obj, $a_parameter)
622  {
623  if (is_object($a_obj))
624  {
625  $this->saveParameterByClass(get_class($a_obj), $a_parameter);
626  }
627  }
628 
635  function saveParameterByClass($a_class, $a_parameter)
636  {
637  if (is_array($a_parameter))
638  {
639  foreach($a_parameter as $parameter)
640  {
641  $this->save_parameter[strtolower($a_class)][] = $parameter;
642  }
643  }
644  else
645  {
646  $this->save_parameter[strtolower($a_class)][] = $a_parameter;
647  }
648  }
649 
650 
673  public function setParameter(&$a_obj, $a_parameter, $a_value)
674  {
675  $this->parameter[strtolower(get_class($a_obj))][$a_parameter] = $a_value;
676  }
677 
678 
686  public function setParameterByClass($a_class, $a_parameter, $a_value)
687  {
688  $this->parameter[strtolower($a_class)][$a_parameter] = $a_value;
689  }
690 
691 
698  public function clearParameters(&$a_obj)
699  {
700  $this->clearParametersByClass(strtolower(get_class($a_obj)));
701  }
702 
709  public function clearParametersByClass($a_class)
710  {
711  $this->parameter[strtolower($a_class)] = array();
712  }
713 
722  function getNextClass()
723  {
724  $cmdNode = $this->getCmdNode();
725 //echo "<br>getNextClass (current node: ".$this->current_node."; cmd node: ".$cmdNode.") ";
726  if ($cmdNode == "")
727  {
728  return false;
729  }
730  else
731  {
732  if ($this->current_node == $cmdNode)
733  {
734 //echo "1:".$this->call_node[$cmdNode]["class"]."<br>";
735  //return $this->call_node[$cmdNode]["class"];
736  return "";
737  }
738  else
739  {
740  $path = $this->getPathNew($this->current_node, $cmdNode);
741 //var_dump($path);
742 //echo " - Next Node: ".$path[1];
743  $this->readCidInfo($this->getCurrentCidOfNode($path[1]));
744 //echo ":".$this->cid_class[$this->getCurrentCidOfNode($path[1])].":".$this->getCurrentCidOfNode($path[1]).":";
745  return $this->cid_class[$this->getCurrentCidOfNode($path[1])];
746  }
747  }
748  }
749 
756  function lookupClassPath($a_class_name)
757  {
758  global $ilDB;
759  $a_class_name = strtolower($a_class_name);
760 
761  $class_set = $ilDB->query("SELECT * FROM ctrl_classfile WHERE class = ".
762  $ilDB->quote($a_class_name, "text"));
763  $class_rec = $ilDB->fetchAssoc($class_set);
764 
765  if ($class_rec["plugin_path"] != "")
766  {
767  return $class_rec["plugin_path"]."/".$class_rec["filename"];
768  }
769  else
770  {
771  return $class_rec["filename"];
772  }
773  }
774 
783  function getClassForClasspath($a_class_path)
784  {
785  $path = pathinfo($a_class_path);
786  $file = $path["basename"];
787  $class = substr($file, 6, strlen($file) - 10);
788 
789  return $class;
790  }
791 
798  private function getPathNew($a_source_node, $a_target_node)
799  {
800 //if ($this->getCmdClass() == "ilmailfoldergui") echo "-".$a_source_node."-".$a_target_node."-";
801 //echo "-".$a_source_node."-".$a_target_node."-";
802 //echo "<br>:::$a_source_node:::";
803  if ($a_source_node == "1")
804  {
805  $a_source_node = "";
806  }
807  if (substr($a_target_node, 0, strlen($a_source_node)) != $a_source_node)
808  {
809  echo "ERROR: Path not found. Source:".$a_source_node.
810  ", Target:".$a_target_node;
811 
812  if (DEVMODE == 1)
813  {
815  }
816  exit;
817  }
818 //echo "<br>:::$a_source_node:::";
819  $temp_node = $a_source_node;
820 
821  $path = array();
822  if ($a_source_node != "")
823  {
824  $path = array($a_source_node);
825  }
826 
827  $diffstart = ($a_source_node == "")
828  ? 0
829  : strlen($a_source_node) + 1;
830  $diff = substr($a_target_node, $diffstart);
831 //echo "=$diff=$diffstart=";
832  $diff_arr = explode(":", $diff);
833  foreach($diff_arr as $cid)
834  {
835  if ($temp_node != "")
836  {
837  $temp_node.= ":";
838  }
839  $temp_node.= $cid;
840  $path[] = $temp_node;
841  }
842 //if ($this->getCmdClass() == "ilmailfoldergui") var_dump($path);
843 //var_dump($path);
844  return $path;
845  }
846 
852  public function setTargetScript($a_target_script)
853  {
854  $this->target_script = $a_target_script;
855  }
856 
857 
863  public function getTargetScript()
864  {
865  return $this->target_script;
866  }
867 
868 
877  public function initBaseClass($a_base_class)
878  {
879  $_GET["baseClass"] = $a_base_class;
880  $_GET["cmd"] = "";
881  $_GET["cmdClass"] = "";
882  $_GET["cmdNode"] = "";
883  $this->init();
884  }
885 
893  public function getCmd($a_default_cmd = "", $a_safe_commands = "")
894  {
895  $cmd = "";
896  if (isset($_GET["cmd"]))
897  {
898  $cmd = $_GET["cmd"];
899  }
900  if($cmd == "post")
901  {
902  if (isset($_POST["cmd"]) && is_array($_POST["cmd"]))
903  {
904  reset($_POST["cmd"]);
905  }
906  $cmd = @key($_POST["cmd"]);
907 
908  // verify command
909  if ($this->verified_cmd != "")
910  {
911  return $this->verified_cmd;
912  }
913  else
914  {
915  if (!$this->verifyToken() &&
916  (!is_array($a_safe_commands) || !in_array($cmd, $a_safe_commands)))
917  {
918  return $a_default_cmd;
919  }
920  }
921 
922  $this->verified_cmd = $cmd;
923  if($cmd == "" && isset($_POST["table_top_cmd"])) // selected command in multi-list (table2)
924  {
925  $cmd = @key($_POST["table_top_cmd"]);
926  $this->verified_cmd = $cmd;
927  $_POST[$_POST["cmd_sv"][$cmd]] = $_POST[$_POST["cmd_sv"][$cmd]."_2"];
928  }
929  if($cmd == "" && isset($_POST["select_cmd2"])) // selected command in multi-list (table2)
930  {
931  $cmd = $_POST["selected_cmd2"];
932  $this->verified_cmd = $cmd;
933  }
934  if($cmd == "" && isset($_POST["select_cmd"])) // selected command in multi-list (table2)
935  {
936  $cmd = $_POST["selected_cmd"];
937  $this->verified_cmd = $cmd;
938  }
939  if($cmd == "")
940  {
941  $cmd = $_GET["fallbackCmd"];
942  $this->verified_cmd = $cmd;
943  }
944  }
945  if($cmd == "")
946  {
947  $cmd = $a_default_cmd;
948  }
949  return $cmd;
950  }
951 
962  function setCmd($a_cmd)
963  {
964  $_GET["cmd"] = $a_cmd;
965  }
966 
977  public function setCmdClass($a_cmd_class)
978  {
979  $a_cmd_class = strtolower($a_cmd_class);
980  $nr = $this->getNodeIdForTargetClass($this->current_node, $a_cmd_class);
981  $_GET["cmdClass"] = $a_cmd_class;
982  $_GET["cmdNode"] = $nr;
983  }
984 
990  function getCmdClass()
991  {
992  return strtolower($_GET["cmdClass"]);
993  }
994 
1005  function getFormAction(&$a_gui_obj, $a_fallback_cmd = "", $a_anchor = "", $a_asynch = false,
1006  $xml_style = true)
1007  {
1008  $script = $this->getFormActionByClass(strtolower(get_class($a_gui_obj)),
1009  $a_fallback_cmd, $a_anchor, $a_asynch, $xml_style);
1010  return $script;
1011  }
1012 
1023  function getFormActionByClass($a_class, $a_fallback_cmd = "", $a_anchor = "", $a_asynch = false,
1024  $xml_style = true)
1025  {
1026  if(!is_array($a_class))
1027  {
1028  $a_class = strtolower($a_class);
1029  }
1030 
1031  $tok = $this->getRequestToken();
1032 
1033  if ($a_asynch)
1034  {
1035  $xml_style = false;
1036  }
1037 
1038  $script = $this->getLinkTargetByClass($a_class, "post", "", $a_asynch);
1039  if ($a_fallback_cmd != "")
1040  {
1041  $script = ilUtil::appendUrlParameterString($script, "fallbackCmd=".$a_fallback_cmd, $xml_style);
1042  }
1043  $script = ilUtil::appendUrlParameterString($script, self::IL_RTOKEN_NAME.'='.$this->getRequestToken(),
1044  $xml_style);
1045  if ($a_anchor != "")
1046  {
1047  $script = $script."#".$a_anchor;
1048  }
1049 
1050  return $script;
1051  }
1052 
1059  public function appendRequestTokenParameterString($a_url, $xml_style = true)
1060  {
1061  return ilUtil::appendUrlParameterString($a_url, self::IL_RTOKEN_NAME.'='.$this->getRequestToken(),
1062  $xml_style);
1063  }
1064 
1070  public function getRequestToken()
1071  {
1072  global $ilDB, $ilUser;
1073 
1074  if ($this->rtoken != "")
1075  {
1076  return $this->rtoken;
1077  }
1078  else
1079  {
1080  if (is_object($ilDB) && is_object($ilUser) && $ilUser->getId() > 0 &&
1081  $ilUser->getId() != ANONYMOUS_USER_ID)
1082  {
1083  $res = $ilDB->query("SELECT token FROM il_request_token WHERE user_id = ".
1084  $ilDB->quote($ilUser->getId(), "integer").
1085  " AND session_id = ".$ilDB->quote(session_id(), "text"));
1086  $rec = $ilDB->fetchAssoc($res);
1087 
1088  if ($rec["token"] != "")
1089  {
1090  $this->rtoken = $rec["token"];
1091  return $rec["token"];
1092  }
1093 
1094  $this->rtoken = md5(uniqid(rand(), true));
1095 
1096  // delete entries older than one and a half days
1097  if (rand(1, 200) == 2)
1098  {
1099  $dt = new ilDateTime(time(),IL_CAL_UNIX);
1100  $dt->increment(IL_CAL_DAY, -1);
1101  $dt->increment(IL_CAL_HOUR, -12);
1102  $dq = "DELETE FROM il_request_token WHERE ".
1103  " stamp < ".$ilDB->quote($dt->get(IL_CAL_DATETIME), "timestamp");
1104  $ilDB->manipulate($dq);
1105  }
1106 
1107  // IMPORTANT: Please do NOT try to move this implementation to a
1108  // session basis. This will fail due to framesets that are used
1109  // occasionally in ILIAS, e.g. in the chat, where multiple
1110  // forms are loaded in different frames.
1111  $ilDB->manipulate("INSERT INTO il_request_token (user_id, token, stamp, session_id) VALUES ".
1112  "(".
1113  $ilDB->quote($ilUser->getId(), "integer").",".
1114  $ilDB->quote($this->rtoken, "text").",".
1115  $ilDB->now().",".
1116  $ilDB->quote(session_id(), "text").")");
1117  return $this->rtoken;
1118  }
1119  //$this->rtoken = md5(uniqid(rand(), true));
1120  }
1121  return "";
1122  }
1123 
1129  private function verifyToken()
1130  {
1131  global $ilDB, $ilUser;
1132 
1133  if (is_object($ilUser) && is_object($ilDB) && $ilUser->getId() > 0 &&
1134  $ilUser->getId() != ANONYMOUS_USER_ID)
1135  {
1136  if ($_GET["rtoken"] == "")
1137  {
1138  #echo "ilCtrl::No Request Token Given!"; // for debugging, maybe changed later
1139  return false;
1140  }
1141 
1142  $set = $ilDB->query("SELECT * FROM il_request_token WHERE ".
1143  " user_id = ".$ilDB->quote($ilUser->getId(), "integer")." AND ".
1144  " token = ".$ilDB->quote($_GET[self::IL_RTOKEN_NAME]), "text");
1145  if ($ilDB->numRows($set) > 0)
1146  {
1147  // remove used token
1148  /*
1149  $ilDB->query("DELETE FROM il_request_token WHERE ".
1150  " user_id = ".$ilDB->quote($ilUser->getId())." AND ".
1151  " token = ".$ilDB->quote($_GET[self::IL_RTOKEN_NAME]));
1152  */
1153 
1154  // remove tokens from older sessions
1155  $ilDB->manipulate("DELETE FROM il_request_token WHERE ".
1156  " user_id = ".$ilDB->quote($ilUser->getId(), "integer")." AND ".
1157  " session_id != ".$ilDB->quote(session_id(), "text"));
1158  return true;
1159  }
1160  else
1161  {
1162  return false;
1163  }
1164 
1165  if ($_SESSION["rtokens"][$_GET[self::IL_RTOKEN_NAME]] != "")
1166  {
1167  // remove used token
1168  unset($_SESSION["rtokens"][$_GET[self::IL_RTOKEN_NAME]]);
1169 
1170  // remove old tokens
1171  if (count($_SESSION["rtokens"]) > 100)
1172  {
1173  $to_remove = array();
1174  $sec = 7200; // two hours
1175 
1176  foreach($_SESSION["rtokens"] as $tok => $time)
1177  {
1178  if (time() - $time > $sec)
1179  {
1180  $to_remove[] = $tok;
1181  }
1182  }
1183  foreach($to_remove as $tok)
1184  {
1185  unset($_SESSION["rtokens"][$tok]);
1186  }
1187  }
1188 
1189  return true;
1190  }
1191  return false;
1192  }
1193  else
1194  {
1195  return true; // do not verify, if user or db object is missing
1196  }
1197 
1198  return false;
1199  }
1200 
1208  public function redirect(&$a_gui_obj, $a_cmd = "", $a_anchor = "", $a_asynch = false)
1209  {
1210  global $ilBench;
1211 
1212  $script = $this->getLinkTargetByClass(strtolower(get_class($a_gui_obj)), $a_cmd,
1213  "", $a_asynch, false);
1214  if (is_object($ilBench))
1215  {
1216  $ilBench->save();
1217  }
1218  if ($a_anchor != "")
1219  {
1220  $script = $script."#".$a_anchor;
1221  }
1222  ilUtil::redirect($script);
1223  }
1224 
1225 
1232  public function redirectByClass($a_class, $a_cmd = "", $a_anchor = "", $a_asynch = false)
1233  {
1234  $script = $this->getLinkTargetByClass($a_class, $a_cmd, "", $a_asynch, false);
1235  if ($a_anchor != "")
1236  {
1237  $script = $script."#".$a_anchor;
1238  }
1239  ilUtil::redirect($script);
1240  }
1241 
1247  public function isAsynch()
1248  {
1249  if (isset($_GET["cmdMode"]) && $_GET["cmdMode"] == "asynch")
1250  {
1251  return true;
1252  }
1253  else
1254  {
1255  return false;
1256  }
1257  }
1258 
1259 
1271  function getLinkTarget(&$a_gui_obj, $a_cmd = "", $a_anchor = "", $a_asynch = false,
1272  $xml_style = true)
1273  {
1274  $script = $this->getLinkTargetByClass(strtolower(get_class($a_gui_obj)), $a_cmd, $a_anchor, $a_asynch,
1275  $xml_style);
1276  return $script;
1277  }
1278 
1279 
1291  function getLinkTargetByClass($a_class, $a_cmd = "", $a_anchor = "", $a_asynch = false,
1292  $xml_style = true)
1293  {
1294  if ($a_asynch)
1295  {
1296  $xml_style = false;
1297  }
1298 
1299  // note: $a_class may be an array
1300  //$a_class = strtolower($a_class);
1301 
1302 //echo "<br>getLinkTargetByClass";
1303  $script = $this->getTargetScript();
1304  $script = $this->getUrlParameters($a_class, $script, $a_cmd, $xml_style);
1305 
1306  if ($a_asynch)
1307  {
1308  //$amp = $xml_style
1309  // ? "&amp;"
1310  // : "&";
1311  $amp = "&";
1312  $script.= $amp."cmdMode=asynch";
1313  }
1314 
1315  if ($a_anchor != "")
1316  {
1317  $script = $script."#".$a_anchor;
1318  }
1319 
1320  return $script;
1321  }
1322 
1326  function setReturn(&$a_gui_obj, $a_cmd)
1327  {
1328  $script = $this->getTargetScript();
1329  $script = $this->getUrlParameters(strtolower(get_class($a_gui_obj)), $script, $a_cmd);
1330 //echo "<br>setReturn:".get_class($a_gui_obj).":".$script.":<br>";
1331  $this->return[strtolower(get_class($a_gui_obj))] = $script;
1332  }
1333 
1337  function setReturnByClass($a_class, $a_cmd)
1338  {
1339  // may not be an array!
1340  $a_class = strtolower($a_class);
1341 
1342  $script = $this->getTargetScript();
1343  $script = $this->getUrlParameters($a_class, $script, $a_cmd);
1344 //echo "<br>setReturn:".get_class($a_gui_obj).":".$script.":<br>";
1345  $this->return[strtolower($a_class)] = $script;
1346  }
1347 
1351  function returnToParent(&$a_gui_obj, $a_anchor = "")
1352  {
1353  $script = $this->getParentReturn($a_gui_obj);
1354 
1355  $script = ilUtil::appendUrlParameterString($script,
1356  "redirectSource=".strtolower(get_class($a_gui_obj)));
1357  $script = ilUtil::appendUrlParameterString($script,
1358  "cmdMode=".$_GET["cmdMode"]);
1359  if ($a_anchor != "")
1360  {
1361  $script = $script."#".$a_anchor;
1362  }
1363 
1364  ilUtil::redirect($script);
1365  }
1366 
1367 
1374  {
1375  return $_GET["redirectSource"];
1376  }
1377 
1381  function getParentReturn(&$a_gui_obj)
1382  {
1383  return $this->getParentReturnByClass(strtolower(get_class($a_gui_obj)));
1384  }
1385 
1386 
1390  function getParentReturnByClass($a_class)
1391  {
1392  $a_class = strtolower($a_class);
1393  $ret_class = $this->searchReturnClass($a_class);
1394 //echo ":$ret_class:";
1395  if($ret_class)
1396  {
1397 //echo ":".$this->return[$ret_class].":";
1398  return $this->return[$ret_class];
1399  }
1400  }
1401 
1408  function getReturnClass($a_class)
1409  {
1410  if (is_object($a_class))
1411  {
1412  $class = strtolower(get_class($a_class));
1413  }
1414  else
1415  {
1416  $class = strtolower($a_class);
1417  }
1418  return $this->searchReturnClass($class);
1419  }
1420 
1421 
1425  private function searchReturnClass($a_class)
1426  {
1427  $a_class = strtolower($a_class);
1428 
1429  $node = $this->getNodeIdForTargetClass($this->current_node, $a_class);
1430  $n_arr = explode(":", $node);
1431  for($i = count($n_arr)-2; $i>=0; $i--)
1432  {
1433  if ($this->return[$this->getClassForCid($n_arr[$i])] != "")
1434  {
1435  return $this->getClassForCid($n_arr[$i]);
1436  }
1437  }
1438 
1439  return false;
1440  }
1441 
1445  public function getUrlParameters($a_class, $a_str, $a_cmd = "", $xml_style = false)
1446  {
1447  // note: $a_class may be an array!
1448  //$a_class = strtolower($a_class);
1449 
1450  $params = $this->getParameterArrayByClass($a_class, $a_cmd);
1451 
1452  foreach ($params as $par => $value)
1453  {
1454  if (strlen((string) $value))
1455  {
1456  $a_str = ilUtil::appendUrlParameterString($a_str, $par."=".$value, $xml_style);
1457  }
1458  }
1459 
1460  return $a_str;
1461  }
1462 
1466  public function getParameterArray(&$a_gui_obj, $a_cmd = "")
1467  {
1468  $par_arr = $this->getParameterArrayByClass(strtolower(get_class($a_gui_obj)), $a_cmd);
1469 
1470  return $par_arr;
1471  }
1472 
1480  public function getParameterArrayByClass($a_class, $a_cmd = "")
1481  {
1482  if ($a_class == "")
1483  {
1484  return array();
1485  }
1486 
1487  if (!is_array($a_class))
1488  {
1489  $a_class = array($a_class);
1490  }
1491 
1492  $nr = $this->current_node;
1493  foreach ($a_class as $class)
1494  {
1495  $class = strtolower($class);
1496  $nr = $this->getNodeIdForTargetClass($nr, $class);
1497  $target_class = $class;
1498  }
1499 
1500  $path = $this->getPathNew(1, $nr);
1501  $params = array();
1502 
1503  // append parameters of parent classes
1504  foreach($path as $node_id)
1505  {
1506  $class = ($node_id == "")
1507  ? strtolower($_GET["baseClass"])
1508  : $this->getClassForCid($this->getCurrentCidOfNode($node_id));
1509  if (isset($this->save_parameter[$class]) && is_array($this->save_parameter[$class]))
1510  {
1511  foreach($this->save_parameter[$class] as $par)
1512  {
1513  if (isset($_GET[$par]))
1514  {
1515  $params[$par] = $_GET[$par];
1516  }
1517  else if (isset($_POST[$par]))
1518  {
1519  $params[$par] = $_POST[$par];
1520  }
1521  }
1522  }
1523 
1524  if (isset($this->parameter[$class]) && is_array($this->parameter[$class]))
1525  {
1526  foreach($this->parameter[$class] as $par => $value)
1527  {
1528  $params[$par] = $value;
1529  }
1530  }
1531  }
1532 
1533  if ($a_cmd != "")
1534  {
1535  $params["cmd"] = $a_cmd;
1536  }
1537 
1538  $params["cmdClass"] = $target_class;
1539  $params["cmdNode"] = $nr;
1540  $params["baseClass"] = $_GET["baseClass"];
1541 
1542  return $params;
1543  }
1544 
1548  private function getCidForClass($a_class, $a_check = false)
1549  {
1550  if ($this->class_cid[$a_class] == "")
1551  {
1552  $this->readClassInfo($a_class);
1553  }
1554  if ($this->class_cid[$a_class] == "")
1555  {
1556  if ($a_check)
1557  {
1558  return false;
1559  }
1560  if (DEVMODE == 1)
1561  {
1562  $add = "<br><br>Please make sure your GUI class name ends with 'GUI' and that the filename is 'class.[YourClassName].php'. In exceptional cases you
1563  may solve the issue by putting an empty * @ilCtrl_Calls [YourClassName]: into your class header.".
1564  " In both cases you need to reload the control structure in the setup.";
1565  }
1566  die("Cannot find cid for class ".$a_class.".".$add);
1567  }
1568  return $this->class_cid[$a_class];
1569  }
1570 
1574  private function getClassForCid($a_cid)
1575  {
1576  if ($this->cid_class[$a_cid] == "")
1577  {
1578  $this->readCidInfo($a_cid);
1579  }
1580  if ($this->cid_class[$a_cid] == "")
1581  {
1582  die("Cannot find class for cid ".$a_cid.".");
1583  }
1584  return $this->cid_class[$a_cid];
1585  }
1586 
1592  private function readCidInfo($a_cid)
1593  {
1594  global $ilDB;
1595 
1596  if (isset($this->info_read_cid[$a_cid]))
1597  {
1598  return;
1599  }
1600  $set = $ilDB->query("SELECT * FROM ctrl_classfile ".
1601  " WHERE cid = ".$ilDB->quote($a_cid, "text")
1602  );
1603  if ($rec = $ilDB->fetchAssoc($set))
1604  {
1605  $this->cid_class[$a_cid] = $rec["class"];
1606  $this->class_cid[$rec["class"]] = $a_cid;
1607 
1608  $set = $ilDB->query("SELECT * FROM ctrl_calls ".
1609  " WHERE parent = ".$ilDB->quote($rec["class"], "text")
1610  );
1611  while ($rec2 = $ilDB->fetchAssoc($set))
1612  {
1613  if (!isset($this->calls[$rec["class"]]) || !is_array($this->calls[$rec["class"]]) || !in_array($rec2["child"], $this->calls[$rec["class"]]))
1614  {
1615  if ($rec2["child"] != "")
1616  {
1617  $this->calls[$rec["class"]][] = $rec2["child"];
1618  }
1619  }
1620  }
1621  $this->info_read_class[$rec["class"]] = true;
1622  }
1623 
1624  $this->info_read_cid[$a_cid] = true;
1625  }
1626 
1632  private function readNodeInfo($a_node)
1633  {
1634  $n_arr = explode(":", $a_node);
1635  foreach ($n_arr as $cid)
1636  {
1637  $this->readCidInfo($cid);
1638  }
1639  }
1640 
1646  private function readClassInfo($a_class)
1647  {
1648  global $ilDB;
1649 
1650  $a_class = strtolower($a_class);
1651  if (isset($this->info_read_class[$a_class]))
1652  {
1653  return;
1654  }
1655  $set = $ilDB->query("SELECT * FROM ctrl_classfile ".
1656  " WHERE class = ".$ilDB->quote($a_class, "text")
1657  );
1658  if ($rec = $ilDB->fetchAssoc($set))
1659  {
1660  $this->cid_class[$rec["cid"]] = $a_class;
1661  $this->class_cid[$a_class] = $rec["cid"];
1662  }
1663 
1664  $set = $ilDB->query("SELECT * FROM ctrl_calls ".
1665  " WHERE parent = ".$ilDB->quote($a_class, "text")
1666  );
1667  while ($rec = $ilDB->fetchAssoc($set))
1668  {
1669  if (!isset($this->calls[$a_class]) || !is_array($this->calls[$a_class]) || !in_array($rec["child"], $this->calls[$a_class]))
1670  {
1671  if ($rec["child"] != "")
1672  {
1673  $this->calls[$a_class][] = $rec["child"];
1674  }
1675  }
1676  }
1677 
1678  $this->info_read_class[$a_class] = true;
1679  $this->info_read_cid[$this->class_cid[$a_class]] = true;
1680  }
1681 
1685  private function getParentCidOfNode($a_node)
1686  {
1687  $n_arr = explode(":", $a_node);
1688  return $n_arr[count($n_arr) - 2];
1689  }
1690 
1694  private function removeLastCid($a_node)
1695  {
1696  $lpos = strrpos($a_node, ":");
1697  return substr($a_node, 0, $lpos);
1698  }
1699 
1703  private function getCurrentCidOfNode($a_node)
1704  {
1705  $n_arr = explode(":", $a_node);
1706  return $n_arr[count($n_arr) - 1];
1707  }
1708 
1715  function insertCtrlCalls($a_parent, $a_child, $a_comp_prefix)
1716  {
1717  global $ilDB;
1718 
1719  $a_parent = strtolower($a_parent);
1720  $a_child = strtolower($a_child);
1721  $a_comp_prefix = strtolower($a_comp_prefix);
1722 
1723  $set = $ilDB->query("SELECT * FROM ctrl_calls WHERE ".
1724  " parent = ".$ilDB->quote($a_parent, "text")." AND ".
1725  " child = ".$ilDB->quote($a_child, "text")." AND ".
1726  " comp_prefix = ".$ilDB->quote($a_comp_prefix, "text")
1727  );
1728  if ($rec = $ilDB->fetchAssoc($set))
1729  {
1730  return;
1731  }
1732  $ilDB->manipulate("INSERT INTO ctrl_calls ".
1733  "(parent, child, comp_prefix) VALUES (".
1734  $ilDB->quote($a_parent, "text").",".
1735  $ilDB->quote($a_child, "text").",".
1736  $ilDB->quote($a_comp_prefix, "text").
1737  ")");
1738  }
1739 
1740 }
1741 ?>