ILIAS  Release_4_0_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.ilCtrl2.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (c) 1998-2009 ILIAS open source, Extended GPL, see docs/LICENSE */
3 
4 include_once("./classes/class.ilCtrl.php");
5 
13 class ilCtrl2 extends ilCtrl
14 {
18  function getCurrentCidOfNode($a_node)
19  {
20  $n_arr = explode(":", $a_node);
21  return $n_arr[count($n_arr) - 1];
22  }
23 
27  function removeLastCid($a_node)
28  {
29  $lpos = strrpos($a_node, ":");
30  return substr($a_node, 0, $lpos);
31  }
32 
36  function getParentCidOfNode($a_node)
37  {
38  $n_arr = explode(":", $a_node);
39  return $n_arr[count($n_arr) - 2];
40  }
41 
42  function getNodeIdForTargetClass($a_par_node, $a_class)
43  {
44  $class = strtolower($a_class);
45  $this->readClassInfo($class);
46 
47  if ($a_par_node === 0 || $a_par_node == "")
48  {
49  return $this->getCidForClass($class);
50  }
51 
52 //return parent::getNodeIdForTargetClass($a_par_node, $a_class);
53  $this->readNodeInfo($a_par_node);
54 
55  $node_cid = $this->getCurrentCidOfNode($a_par_node);
56 
57  // target class is class of current node id
58  if ($class == $this->getClassForCid($node_cid))
59  {
60  return $a_par_node;
61  }
62 
63  // target class is child of current node id
64  if (is_array($this->calls[$this->getClassForCid($node_cid)]) &&
65  in_array($a_class, $this->calls[$this->getClassForCid($node_cid)]))
66  {
67  return $a_par_node.":".$this->getCidForClass($class);
68  }
69 
70  // target class is sibling
71  $par_cid = $this->getParentCidOfNode($a_par_node);
72  if ($par_cid != "")
73  {
74  if (is_array($this->calls[$this->getClassForCid($par_cid)]) &&
75  in_array($a_class, $this->calls[$this->getClassForCid($par_cid)]))
76  {
77  return $this->removeLastCid($a_par_node).":".$this->getCidForClass($class);;
78  }
79  }
80 
81  // target class is parent
82  $temp_node = $this->removeLastCid($a_par_node);
83  while($temp_node != "")
84  {
85  $temp_cid = $this->getCurrentCidOfNode($temp_node);
86  if ($this->getClassForCid($temp_cid) == $a_class)
87  {
88  return $temp_node;
89  }
90  $temp_node = $this->removeLastCid($temp_node);
91  }
92 
93  // Please do NOT change these lines.
94  // Developers must be aware, if they use classes unknown to the controller
95  // otherwise certain problem will be extremely hard to track down...
96  echo "ERROR: Can't find target class $a_class for node $a_par_node ".
97  "(".$this->cid_class[$this->getParentCidOfNode($a_par_node)].").<br>";
98  error_log( "ERROR: Can't find target class $a_class for node $a_par_node ".
99  "(".$this->cid_class[$this->getParentCidOfNode($a_par_node)].")");
100 
101  if (DEVMODE == 1)
102  {
103  try
104  {
105  throw new Exception("");
106  }
107  catch(Exception $e)
108  {
109  echo "<pre>".$e->getTraceAsString()."</pre>";
110  }
111  }
112 
113  exit;
114  }
115 
116  function getCallStructure($a_class)
117  {
118  $this->readClassInfo($a_class);
119  }
120 
126  function readClassInfo($a_class)
127  {
128  global $ilDB;
129 
130  $a_class = strtolower($a_class);
131  if ($this->info_read_class[$a_class])
132  {
133  return;
134  }
135  $set = $ilDB->query("SELECT * FROM ctrl_classfile ".
136  " WHERE class = ".$ilDB->quote($a_class, "text")
137  );
138  if ($rec = $ilDB->fetchAssoc($set))
139  {
140  $this->cid_class[$rec["cid"]] = $a_class;
141  $this->class_cid[$a_class] = $rec["cid"];
142  }
143 
144  $set = $ilDB->query("SELECT * FROM ctrl_calls ".
145  " WHERE parent = ".$ilDB->quote($a_class, "text")
146  );
147  while ($rec = $ilDB->fetchAssoc($set))
148  {
149  if (!is_array($this->calls[$a_class]) || !in_array($rec["child"], $this->calls[$a_class]))
150  {
151  if ($rec["child"] != "")
152  {
153  $this->calls[$a_class][] = $rec["child"];
154  }
155  }
156  }
157 
158  $this->info_read_class[$a_class] = true;
159  $this->info_read_cid[$this->class_cid[$a_class]] = true;
160  }
161 
167  function readNodeInfo($a_node)
168  {
169  $n_arr = explode(":", $a_node);
170  foreach ($n_arr as $cid)
171  {
172  $this->readCidInfo($cid);
173  }
174  }
175 
181  function readCidInfo($a_cid)
182  {
183  global $ilDB;
184 
185  if ($this->info_read_cid[$a_cid])
186  {
187  return;
188  }
189  $set = $ilDB->query("SELECT * FROM ctrl_classfile ".
190  " WHERE cid = ".$ilDB->quote($a_cid, "text")
191  );
192  if ($rec = $ilDB->fetchAssoc($set))
193  {
194  $this->cid_class[$a_cid] = $rec["class"];
195  $this->class_cid[$rec["class"]] = $a_cid;
196 
197  $set = $ilDB->query("SELECT * FROM ctrl_calls ".
198  " WHERE parent = ".$ilDB->quote($rec["class"], "text")
199  );
200  while ($rec2 = $ilDB->fetchAssoc($set))
201  {
202  if (!is_array($this->calls[$rec["class"]]) || !in_array($rec2["child"], $this->calls[$rec["class"]]))
203  {
204  if ($rec2["child"] != "")
205  {
206  $this->calls[$rec["class"]][] = $rec2["child"];
207  }
208  }
209  }
210  $this->info_read_class[$rec["class"]] = true;
211  }
212 
213  $this->info_read_cid[$a_cid] = true;
214  }
215 
219  function getCidForClass($a_class)
220  {
221  if ($this->class_cid[$a_class] == "")
222  {
223  $this->readClassInfo($a_class);
224  }
225  if ($this->class_cid[$a_class] == "")
226  {
227  if (DEVMODE == 1)
228  {
229  $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
230  may solve the issue by putting an empty * @ilCtrl_Calls [YourClassName]: into your class header.".
231  " In both cases you need to reload the control structure in the setup.";
232  }
233  die("Cannot find cid for class ".$a_class.".".$add);
234  }
235  return $this->class_cid[$a_class];
236  }
237 
241  function getClassForCid($a_cid)
242  {
243  if ($this->cid_class[$a_cid] == "")
244  {
245  $this->readCidInfo($a_cid);
246  }
247  if ($this->cid_class[$a_cid] == "")
248  {
249  die("Cannot find class for cid ".$a_cid.".");
250  }
251  return $this->cid_class[$a_cid];
252  }
253 
260  function getPathNew($a_source_node, $a_target_node)
261  {
262 //if ($this->getCmdClass() == "ilmailfoldergui") echo "-".$a_source_node."-".$a_target_node."-";
263 //echo "-".$a_source_node."-".$a_target_node."-";
264 //echo "<br>:::$a_source_node:::";
265  if ($a_source_node == "1")
266  {
267  $a_source_node = "";
268  }
269  if (substr($a_target_node, 0, strlen($a_source_node)) != $a_source_node)
270  {
271  echo "ERROR: Path not found. Source:".$a_source_node.
272  ", Target:".$a_target_node;
273  exit;
274  }
275 //echo "<br>:::$a_source_node:::";
276  $temp_node = $a_source_node;
277 
278  $path = array();
279  if ($a_source_node != "")
280  {
281  $path = array($a_source_node);
282  }
283 
284  $diffstart = ($a_source_node == "")
285  ? 0
286  : strlen($a_source_node) + 1;
287  $diff = substr($a_target_node, $diffstart);
288 //echo "=$diff=$diffstart=";
289  $diff_arr = explode(":", $diff);
290  foreach($diff_arr as $cid)
291  {
292  if ($temp_node != "")
293  {
294  $temp_node.= ":";
295  }
296  $temp_node.= $cid;
297  $path[] = $temp_node;
298  }
299 //if ($this->getCmdClass() == "ilmailfoldergui") var_dump($path);
300 //var_dump($path);
301  return $path;
302  }
303 
307  function searchReturnClass($a_class)
308  {
309  $a_class = strtolower($a_class);
310 
311  $node = $this->getNodeIdForTargetClass($this->current_node, $a_class);
312  $n_arr = explode(":", $node);
313  for($i = count($n_arr)-2; $i>=0; $i--)
314  {
315  if ($this->return[$this->getClassForCid($n_arr[$i])] != "")
316  {
317  return $this->getClassForCid($n_arr[$i]);
318  }
319  }
320 
321  return false;
322  }
323 
324 
327 
339  function &forwardCommand(&$a_gui_object)
340  {
341  $class = strtolower(get_class($a_gui_object));
342 //echo "<br>forward to $class";
343  $nr = $this->getNodeIdForTargetClass($this->current_node, $class);
344  if ($nr != "")
345  {
346  $current_node = $this->current_node;
347 
348  $this->current_node = $nr;
349 
350  if (DEVMODE == "1")
351  {
352  $this->call_hist[] = array("class" => get_class($a_gui_object),
353  "mode" => "execComm", "cmd" => $this->getCmd());
354  }
355 //echo "<br>class:".get_class($a_gui_object).":";
356  $html = $a_gui_object->executeCommand();
357 
358  // reset current node
359  $this->current_node = $current_node;
360 
361  return $html;
362 
363  }
364  echo "ERROR: Can't forward to class $class."; exit;
365 //echo "end forward<br>";
366  }
367 
377  function &getHTML(&$a_gui_object)
378  {
379  $class = strtolower(get_class($a_gui_object));
380 
381  $nr = $this->getNodeIdForTargetClass($this->current_node, $class);
382  if ($nr != "")
383  {
384  $current_node = $this->current_node;
385 
386  // set current node to new gui class
387  $this->current_node = $nr;
388 
389  if (DEVMODE == "1")
390  {
391  $this->call_hist[] = array("class" => get_class($a_gui_object),
392  "mode" => "getHtml", "cmd" => $this->getCmd());
393  }
394 
395  // get block
396  $html = $a_gui_object->getHTML();
397 
398  // reset current node
399  $this->current_node = $current_node;
400 
401  // return block
402  return $html;
403  }
404  echo "ERROR: Can't getHTML from class $class."; exit;
405  }
406 
415  function getNextClass()
416  {
417  $cmdNode = $this->getCmdNode();
418 //echo "<br>getNextClass (current node: ".$this->current_node."; cmd node: ".$cmdNode.") ";
419  if ($cmdNode == "")
420  {
421  return false;
422  }
423  else
424  {
425  if ($this->current_node == $cmdNode)
426  {
427 //echo "1:".$this->call_node[$cmdNode]["class"]."<br>";
428  //return $this->call_node[$cmdNode]["class"];
429  return "";
430  }
431  else
432  {
433  $path = $this->getPathNew($this->current_node, $cmdNode);
434 //var_dump($path);
435 //echo " - Next Node: ".$path[1];
436  $this->readCidInfo($this->getCurrentCidOfNode($path[1]));
437 //echo ":".$this->cid_class[$this->getCurrentCidOfNode($path[1])].":".$this->getCurrentCidOfNode($path[1]).":";
438  return $this->cid_class[$this->getCurrentCidOfNode($path[1])];
439  }
440  }
441  }
442 
446  function getParameterArrayByClass($a_class, $a_cmd = "")
447  {
448  if ($a_class == "")
449  {
450  return array();
451  }
452 
453  if (!is_array($a_class))
454  {
455  $a_class = array($a_class);
456  }
457 
458  $nr = $this->current_node;
459  foreach ($a_class as $class)
460  {
461  $class = strtolower($class);
462  $nr = $this->getNodeIdForTargetClass($nr, $class);
463  $target_class = $class;
464  }
465 
466  $path = $this->getPathNew(1, $nr);
467  $params = array();
468 
469  // append parameters of parent classes
470  foreach($path as $node_id)
471  {
472  $class = ($node_id == "")
473  ? strtolower($_GET["baseClass"])
474  : $this->getClassForCid($this->getCurrentCidOfNode($node_id));
475  if (is_array($this->save_parameter[$class]))
476  {
477  foreach($this->save_parameter[$class] as $par)
478  {
479  $params[$par] = $_GET[$par];
480  }
481  }
482 
483  if (is_array($this->parameter[$class]))
484  {
485  foreach($this->parameter[$class] as $par => $value)
486  {
487  $params[$par] = $value;
488  }
489  }
490  }
491 
492  if ($a_cmd != "")
493  {
494  $params["cmd"] = $a_cmd;
495  }
496 
497  $params["cmdClass"] = $target_class;
498  $params["cmdNode"] = $nr;
499  $params["baseClass"] = $_GET["baseClass"];
500 
501  return $params;
502  }
503 
504 }
505 ?>