ILIAS  Release_4_2_x_branch Revision 61807
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.ilPageObject.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 define("IL_INSERT_BEFORE", 0);
5 define("IL_INSERT_AFTER", 1);
6 define("IL_INSERT_CHILD", 2);
7 
8 define ("IL_CHAPTER_TITLE", "st_title");
9 define ("IL_PAGE_TITLE", "pg_title");
10 define ("IL_NO_HEADER", "none");
11 
27 {
28  static $exists = array();
29 
30  var $id;
31  var $ilias;
32  var $dom;
33  var $xml;
34  var $encoding;
35  var $node;
36  var $cur_dtd = "ilias_pg_4_2.dtd";
47 
52  function ilPageObject($a_parent_type, $a_id = 0, $a_old_nr = 0, $a_halt = true)
53  {
54  global $ilias;
55 
56  require_once("./Services/COPage/syntax_highlight/php/Beautifier/Init.php");
57  require_once("./Services/COPage/syntax_highlight/php/Output/Output_css.php");
58 
59  $this->parent_type = $a_parent_type;
60  $this->id = $a_id;
61  $this->ilias =& $ilias;
62 
63  $this->contains_int_link = false;
64  $this->needs_parsing = false;
65  $this->update_listeners = array();
66  $this->update_listener_cnt = 0;
67  $this->dom_builded = false;
68  $this->halt_on_error = $a_halt;
69  $this->page_not_found = false;
70  $this->old_nr = $a_old_nr;
71  $this->layout_mode = false;
72  $this->encoding = "UTF-8";
73  $this->id_elements =
74  array("PageContent", "TableRow", "TableData", "ListItem", "FileItem",
75  "Section", "Tab", "ContentPopup");
76 
77  $this->setActive(true);
78 
79  if($a_id != 0)
80  {
81  $this->read();
82  }
83  }
84 
85  function haltOnError($a_halt)
86  {
87  $this->halt_on_error = $a_halt;
88  }
89 
95  function setRenderMd5($a_rendermd5)
96  {
97  $this->rendermd5 = $a_rendermd5;
98  }
99 
105  function getRenderMd5()
106  {
107  return $this->rendermd5;
108  }
109 
115  function setRenderedContent($a_renderedcontent)
116  {
117  $this->renderedcontent = $a_renderedcontent;
118  }
119 
126  {
127  return $this->renderedcontent;
128  }
129 
135  function setRenderedTime($a_renderedtime)
136  {
137  $this->renderedtime = $a_renderedtime;
138  }
139 
145  function getRenderedTime()
146  {
147  return $this->renderedtime;
148  }
149 
155  function setLastChange($a_lastchange)
156  {
157  $this->lastchange = $a_lastchange;
158  }
159 
165  function getLastChange()
166  {
167  return $this->lastchange;
168  }
169 
175  function setLayoutMode($a_layout_mode)
176  {
177  $this->layout_mode = $a_layout_mode;
178  }
179 
185  function getLayoutMode()
186  {
187  return $this->layout_mode;
188  }
189 
195  public function setLastChangeUser($a_val)
196  {
197  $this->last_change_user = $a_val;
198  }
199 
205  public function getLastChangeUser()
206  {
207  return $this->last_change_user;
208  }
209 
213  function read()
214  {
215  global $ilBench, $ilDB;
216 
217  $ilBench->start("ContentPresentation", "ilPageObject_read");
218 
219  $this->setActive(true);
220  if ($this->old_nr == 0)
221  {
222  $query = "SELECT * FROM page_object WHERE page_id = ".$ilDB->quote($this->id, "integer")." ".
223  "AND parent_type=".$ilDB->quote($this->getParentType(), "text");
224  $pg_set = $this->ilias->db->query($query);
225  $this->page_record = $ilDB->fetchAssoc($pg_set);
226  $this->setActive($this->page_record["active"]);
227  $this->setActivationStart($this->page_record["activation_start"]);
228  $this->setActivationEnd($this->page_record["activation_end"]);
229  }
230  else
231  {
232  $query = "SELECT * FROM page_history WHERE ".
233  "page_id = ".$ilDB->quote($this->id, "integer")." ".
234  "AND parent_type=".$ilDB->quote($this->getParentType(), "text").
235  " AND nr = ".$ilDB->quote((int) $this->old_nr, "integer");
236  $pg_set = $ilDB->query($query);
237  $this->page_record = $ilDB->fetchAssoc($pg_set);
238  }
239  if (!$this->page_record)
240  {
241  if ($this->halt_on_error)
242  {
243  include_once("./Services/COPage/exceptions/class.ilCOPageNotFoundException.php");
244  throw new ilCOPageNotFoundException("Error: Page ".$this->id." is not in database".
245  " (parent type ".$this->getParentType().").");
246  //ilUtil::printBacktrace();
247  return;
248  }
249  else
250  {
251  $this->page_not_found = true;
252  return;
253  }
254  }
255  $this->xml = $this->page_record["content"];
256  $this->setParentId($this->page_record["parent_id"]);
257  $this->last_change_user = $this->page_record["last_change_user"];
258  $this->create_user = $this->page_record["create_user"];
259  $this->setRenderedContent($this->page_record["rendered_content"]);
260  $this->setRenderMd5($this->page_record["render_md5"]);
261  $this->setRenderedTime($this->page_record["rendered_time"]);
262  $this->setLastChange($this->page_record["last_change"]);
263 
264  $ilBench->stop("ContentPresentation", "ilPageObject_read");
265  }
266 
273  static function _exists($a_parent_type, $a_id)
274  {
275  global $ilDB;
276  if (isset(self::$exists[$a_parent_type.":".$a_id]))
277  {
278  return self::$exists[$a_parent_type.":".$a_id];
279  }
280 
281  $query = "SELECT page_id FROM page_object WHERE page_id = ".$ilDB->quote($a_id, "integer")." ".
282  "AND parent_type= ".$ilDB->quote($a_parent_type, "text");
283  $set = $ilDB->query($query);
284  if ($row = $ilDB->fetchAssoc($set))
285  {
286  self::$exists[$a_parent_type.":".$a_id] = true;
287  return true;
288  }
289  else
290  {
291  self::$exists[$a_parent_type.":".$a_id] = false;
292  return false;
293  }
294  }
295 
302  function _existsAndNotEmpty($a_parent_type, $a_id)
303  {
304  global $ilDB;
305 
306  $query = "SELECT page_id, is_empty FROM page_object WHERE page_id = ".$ilDB->quote($a_id, "integer")." ".
307  "AND parent_type= ".$ilDB->quote($a_parent_type, "text");
308 
309  $set = $ilDB->query($query);
310  if ($row = $ilDB->fetchAssoc($set))
311  {
312  if ($row["is_empty"] != 1)
313  {
314  return true;
315  }
316  }
317  return false;
318  }
319 
320  function buildDom($a_force = false)
321  {
322  global $ilBench;
323 
324  if ($this->dom_builded && !$a_force)
325  {
326  return;
327  }
328 
329 //echo "\n<br>buildDomWith:".$this->getId().":xml:".$this->getXMLContent(true).":<br>";
330 
331  $ilBench->start("ContentPresentation", "ilPageObject_buildDom");
332  $this->dom = @domxml_open_mem($this->getXMLContent(true), DOMXML_LOAD_VALIDATING, $error);
333  $ilBench->stop("ContentPresentation", "ilPageObject_buildDom");
334 
335  $xpc = xpath_new_context($this->dom);
336  $path = "//PageObject";
337  $res =& xpath_eval($xpc, $path);
338  if (count($res->nodeset) == 1)
339  {
340  $this->node =& $res->nodeset[0];
341  }
342 
343  if (empty($error))
344  {
345  $this->dom_builded = true;
346  return true;
347  }
348  else
349  {
350  return $error;
351  }
352  }
353 
354  function freeDom()
355  {
356  //$this->dom->free();
357  unset($this->dom);
358  }
359 
360  function &getDom()
361  {
362  return $this->dom;
363  }
364 
368  function setId($a_id)
369  {
370  $this->id = $a_id;
371  }
372 
373  function getId()
374  {
375  return $this->id;
376  }
377 
378  function setParentId($a_id)
379  {
380  $this->parent_id = $a_id;
381  }
382 
383  function getParentId()
384  {
385  return $this->parent_id;
386  }
387 
388  function setParentType($a_type)
389  {
390  $this->parent_type = $a_type;
391  }
392 
393  function getParentType()
394  {
395  return $this->parent_type;
396  }
397 
398  function addUpdateListener(&$a_object, $a_method, $a_parameters = "")
399  {
401  $this->update_listeners[$cnt]["object"] =& $a_object;
402  $this->update_listeners[$cnt]["method"] = $a_method;
403  $this->update_listeners[$cnt]["parameters"] = $a_parameters;
404  $this->update_listener_cnt++;
405  }
406 
408  {
409  for($i=0; $i<$this->update_listener_cnt; $i++)
410  {
411  $object =& $this->update_listeners[$i]["object"];
412  $method = $this->update_listeners[$i]["method"];
413  $parameters = $this->update_listeners[$i]["parameters"];
414  $object->$method($parameters);
415  }
416  }
417 
423  function setActive($a_active)
424  {
425  $this->active = $a_active;
426  }
427 
433  function getActive($a_check_scheduled_activation = false)
434  {
435  if ($a_check_scheduled_activation && !$this->active)
436  {
437  include_once("./Services/Calendar/classes/class.ilDateTime.php");
438  $start = new ilDateTime($this->getActivationStart(), IL_CAL_DATETIME);
439  $end = new ilDateTime($this->getActivationEnd(), IL_CAL_DATETIME);
440  $now = new ilDateTime(time(), IL_CAL_UNIX);
441  if (!ilDateTime::_before($now, $start) && !ilDateTime::_after($now, $end))
442  {
443  return true;
444  }
445  }
446  return $this->active;
447  }
448 
452  function _lookupActive($a_id, $a_parent_type, $a_check_scheduled_activation = false)
453  {
454  global $ilDB;
455 
456  $set = $ilDB->queryF("SELECT active, activation_start, activation_end FROM page_object WHERE page_id = %s".
457  " AND parent_type = %s",
458  array("integer", "text"),
459  array($a_id, $a_parent_type));
460  $rec = $ilDB->fetchAssoc($set);
461  $rec["n"] = ilUtil::now();
462 
463  if (!$rec["active"] && $a_check_scheduled_activation)
464  {
465  if ($rec["n"] >= $rec["activation_start"] &&
466  $rec["n"] <= $rec["activation_end"])
467  {
468  return true;
469  }
470  }
471 
472  return $rec["active"];
473  }
474 
478  static function _isScheduledActivation($a_id, $a_parent_type)
479  {
480  global $ilDB;
481 
482  $set = $ilDB->queryF("SELECT active, activation_start, activation_end FROM page_object WHERE page_id = %s".
483  " AND parent_type = %s", array("integer", "text"),
484  array($a_id, $a_parent_type));
485  $rec = $ilDB->fetchAssoc($set);
486 
487  if (!$rec["active"] && $rec["activation_start"] != "")
488  {
489  return true;
490  }
491 
492  return false;
493  }
494 
498  function _writeActive($a_id, $a_parent_type, $a_active, $a_reset_scheduled_activation = true)
499  {
500  global $ilDB;
501 
502  if ($a_reset_scheduled_activation)
503  {
504  $st = $ilDB->manipulateF("UPDATE page_object SET active = %s, activation_start = %s, ".
505  " activation_end = %s WHERE page_id = %s".
506  " AND parent_type = %s", array("boolean", "timestamp", "timestamp", "integer", "text"),
507  array($a_active, null, null, $a_id, $a_parent_type));
508  }
509  else
510  {
511  $st = $ilDB->prepareManip("UPDATE page_object SET active = %s WHERE page_id = %s".
512  " AND parent_type = %s", array("boolean", "integer", "text"),
513  array($a_active, $a_id, $a_parent_type));
514  }
515  }
516 
520  static function lookupParentId($a_id, $a_type)
521  {
522  global $ilDB;
523 
524  $res = $ilDB->query("SELECT parent_id FROM page_object WHERE page_id = ".$ilDB->quote($a_id, "integer")." ".
525  "AND parent_type=".$ilDB->quote($a_type, "text"));
526  $rec = $ilDB->fetchAssoc($res);
527  return $rec["parent_id"];
528  }
529 
533  function _writeParentId($a_parent_type, $a_pg_id, $a_par_id)
534  {
535  global $ilDB;
536 
537  $st = $ilDB->manipulateF("UPDATE page_object SET parent_id = %s WHERE page_id = %s".
538  " AND parent_type = %s", array("integer", "integer", "text"),
539  array($a_par_id, $a_pg_id, $a_parent_type));
540  }
541 
547  function setActivationStart($a_activationstart)
548  {
549  $this->activationstart = $a_activationstart;
550  }
551 
558  {
559  return $this->activationstart;
560  }
561 
567  function setActivationEnd($a_activationend)
568  {
569  $this->activationend = $a_activationend;
570  }
571 
577  function getActivationEnd()
578  {
579  return $this->activationend;
580  }
581 
590  function &getContentObject($a_hier_id, $a_pc_id = "")
591  {
592 //echo ":".$a_hier_id.":";
593 //echo "Content:".htmlentities($this->getXMLFromDOM()).":<br>";
594 //echo "ilPageObject::getContentObject:hierid:".$a_hier_id.":<br>";
595  $cont_node =& $this->getContentNode($a_hier_id, $a_pc_id);
596 //echo "ilPageObject::getContentObject:nodename:".$cont_node->node_name().":<br>";
597  if (!is_object($cont_node))
598  {
599  return false;
600  }
601  switch($cont_node->node_name())
602  {
603  case "PageContent":
604  $child_node =& $cont_node->first_child();
605 //echo "<br>nodename:".$child_node->node_name();
606  switch($child_node->node_name())
607  {
608  case "Paragraph":
609  require_once("./Services/COPage/classes/class.ilPCParagraph.php");
610  $par =& new ilPCParagraph($this->dom);
611  $par->setNode($cont_node);
612  $par->setHierId($a_hier_id);
613  $par->setPcId($a_pc_id);
614  return $par;
615 
616  case "Table":
617  if ($child_node->get_attribute("DataTable") == "y")
618  {
619  require_once("./Services/COPage/classes/class.ilPCDataTable.php");
620  $tab =& new ilPCDataTable($this->dom);
621  $tab->setNode($cont_node);
622  $tab->setHierId($a_hier_id);
623  }
624  else
625  {
626  require_once("./Services/COPage/classes/class.ilPCTable.php");
627  $tab =& new ilPCTable($this->dom);
628  $tab->setNode($cont_node);
629  $tab->setHierId($a_hier_id);
630  }
631  $tab->setPcId($a_pc_id);
632  return $tab;
633 
634  case "MediaObject":
635 if ($_GET["pgEdMediaMode"] != "") {echo "ilPageObject::error media"; exit;}
636 
637  //require_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
638  require_once("./Services/COPage/classes/class.ilPCMediaObject.php");
639 
640  $mal_node =& $child_node->first_child();
641 //echo "ilPageObject::getContentObject:nodename:".$mal_node->node_name().":<br>";
642  $id_arr = explode("_", $mal_node->get_attribute("OriginId"));
643  $mob_id = $id_arr[count($id_arr) - 1];
644 
645  // allow deletion of non-existing media objects
646  if (!ilObject::_exists($mob_id) && in_array("delete", $_POST))
647  {
648  $mob_id = 0;
649  }
650 
651  //$mob =& new ilObjMediaObject($mob_id);
652  $mob = new ilPCMediaObject($this->dom);
653  $mob->readMediaObject($mob_id);
654 
655  //$mob->setDom($this->dom);
656  $mob->setNode($cont_node);
657  $mob->setHierId($a_hier_id);
658  $mob->setPcId($a_pc_id);
659  return $mob;
660 
661  case "List":
662  require_once("./Services/COPage/classes/class.ilPCList.php");
663  $list = new ilPCList($this->dom);
664  $list->setNode($cont_node);
665  $list->setHierId($a_hier_id);
666  $list->setPcId($a_pc_id);
667  return $list;
668 
669  case "FileList":
670  require_once("./Services/COPage/classes/class.ilPCFileList.php");
671  $file_list = new ilPCFileList($this->dom);
672  $file_list->setNode($cont_node);
673  $file_list->setHierId($a_hier_id);
674  $file_list->setPcId($a_pc_id);
675  return $file_list;
676 
677  // note: assessment handling is forwarded to assessment gui classes
678  case "Question":
679  require_once("./Services/COPage/classes/class.ilPCQuestion.php");
680  $pc_question = new ilPCQuestion($this->dom);
681  $pc_question->setNode($cont_node);
682  $pc_question->setHierId($a_hier_id);
683  $pc_question->setPcId($a_pc_id);
684  return $pc_question;
685 
686  case "Section":
687  require_once("./Services/COPage/classes/class.ilPCSection.php");
688  $sec = new ilPCSection($this->dom);
689  $sec->setNode($cont_node);
690  $sec->setHierId($a_hier_id);
691  $sec->setPcId($a_pc_id);
692  return $sec;
693 
694  case "Resources":
695  require_once("./Services/COPage/classes/class.ilPCResources.php");
696  $res = new ilPCResources($this->dom);
697  $res->setNode($cont_node);
698  $res->setHierId($a_hier_id);
699  $res->setPcId($a_pc_id);
700  return $res;
701 
702  case 'LoginPageElement':
703  include_once './Services/COPage/classes/class.ilPCLoginPageElements.php';
704  $res = new ilPCLoginPageElements($this->dom);
705  $res->setNode($cont_node);
706  $res->setHierId($a_hier_id);
707  $res->setPcId($a_pcid);
708  return $res;
709 
710  case "Map":
711  require_once("./Services/COPage/classes/class.ilPCMap.php");
712  $map = new ilPCMap($this->dom);
713  $map->setNode($cont_node);
714  $map->setHierId($a_hier_id);
715  $map->setPcId($a_pc_id);
716  return $map;
717 
718  case "Tabs":
719  require_once("./Services/COPage/classes/class.ilPCTabs.php");
720  $map = new ilPCTabs($this->dom);
721  $map->setNode($cont_node);
722  $map->setHierId($a_hier_id);
723  $map->setPcId($a_pc_id);
724  return $map;
725 
726  case "Plugged":
727  require_once("./Services/COPage/classes/class.ilPCPlugged.php");
728  $plugged = new ilPCPlugged($this->dom);
729  $plugged->setNode($cont_node);
730  $plugged->setHierId($a_hier_id);
731  $plugged->setPcId($a_pc_id);
732  return $plugged;
733 
734  //Page-Layout-Support
735  case "PlaceHolder":
736  require_once("./Services/COPage/classes/class.ilPCPlaceHolder.php");
737  $placeholder = new ilPCPlaceHolder($this->dom);
738  $placeholder->setNode($cont_node);
739  $placeholder->setHierId($a_hier_id);
740  $placeholder->setPcId($a_pc_id);
741  return $placeholder;
742 
743  case "ContentInclude":
744  require_once("./Services/COPage/classes/class.ilPCContentInclude.php");
745  $inc =& new ilPCContentInclude($this->dom);
746  $inc->setNode($cont_node);
747  $inc->setHierId($a_hier_id);
748  $inc->setPcId($a_pc_id);
749  return $inc;
750 
751  case "InteractiveImage":
752  require_once("./Services/COPage/classes/class.ilPCInteractiveImage.php");
753  $iim = new ilPCInteractiveImage($this->dom);
754  $iim->setNode($cont_node);
755  $iim->setHierId($a_hier_id);
756  $iim->setPcId($a_pc_id);
757  return $iim;
758 
759  case "Profile":
760  require_once("./Services/COPage/classes/class.ilPCProfile.php");
761  $prof = new ilPCProfile($this->dom);
762  $prof->setNode($cont_node);
763  $prof->setHierId($a_hier_id);
764  $prof->setPcId($a_pc_id);
765  return $prof;
766 
767  case "Verification":
768  require_once("./Services/COPage/classes/class.ilPCVerification.php");
769  $vrfc = new ilPCVerification($this->dom);
770  $vrfc->setNode($cont_node);
771  $vrfc->setHierId($a_hier_id);
772  $vrfc->setPcId($a_pc_id);
773  return $vrfc;
774 
775  case "Blog":
776  require_once("./Services/COPage/classes/class.ilPCBlog.php");
777  $blog = new ilPCBlog($this->dom);
778  $blog->setNode($cont_node);
779  $blog->setHierId($a_hier_id);
780  $blog->setPcId($a_pc_id);
781  return $blog;
782 
783  case "QuestionOverview":
784  require_once("./Services/COPage/classes/class.ilPCQuestionOverview.php");
785  $qover = new ilPCQuestionOverview($this->dom);
786  $qover->setNode($cont_node);
787  $qover->setHierId($a_hier_id);
788  $qover->setPcId($a_pc_id);
789  return $qover;
790 
791  case "Skills":
792  require_once("./Services/COPage/classes/class.ilPCSkills.php");
793  $skill = new ilPCSkills($this->dom);
794  $skill->setNode($cont_node);
795  $skill->setHierId($a_hier_id);
796  $skill->setPcId($a_pc_id);
797  return $skill;
798  }
799  break;
800 
801  case "TableData":
802  require_once("./Services/COPage/classes/class.ilPCTableData.php");
803  $td =& new ilPCTableData($this->dom);
804  $td->setNode($cont_node);
805  $td->setHierId($a_hier_id);
806  return $td;
807 
808  case "ListItem":
809  require_once("./Services/COPage/classes/class.ilPCListItem.php");
810  $td =& new ilPCListItem($this->dom);
811  $td->setNode($cont_node);
812  $td->setHierId($a_hier_id);
813  return $td;
814 
815  case "FileItem":
816  require_once("./Services/COPage/classes/class.ilPCFileItem.php");
817  $file_item =& new ilPCFileItem($this->dom);
818  $file_item->setNode($cont_node);
819  $file_item->setHierId($a_hier_id);
820  return $file_item;
821 
822 /* case "Tab":
823  require_once("./Services/COPage/classes/class.ilPCTab.php");
824  $tab =& new ilPCTab($this->dom);
825  $tab->setNode($cont_node);
826  $tab->setHierId($a_hier_id);
827  return $tab;*/
828 
829  }
830  }
831 
838  function &getContentNode($a_hier_id, $a_pc_id = "")
839  {
840  $xpc = xpath_new_context($this->dom);
841  if($a_hier_id == "pg")
842  {
843  return $this->node;
844  }
845  else
846  {
847  // get per pc id
848  if ($a_pc_id != "")
849  {
850  $path = "//*[@PCID = '$a_pc_id']";
851  $res =& xpath_eval($xpc, $path);
852  if (count($res->nodeset) == 1)
853  {
854  $cont_node =& $res->nodeset[0];
855  return $cont_node;
856  }
857  }
858 
859  // fall back to hier id
860  $path = "//*[@HierId = '$a_hier_id']";
861  $res =& xpath_eval($xpc, $path);
862  if (count($res->nodeset) == 1)
863  {
864  $cont_node =& $res->nodeset[0];
865  return $cont_node;
866  }
867  }
868  }
869 
876  function checkForTag($a_content_tag, $a_hier_id, $a_pc_id = "")
877  {
878  $xpc = xpath_new_context($this->dom);
879  // get per pc id
880  if ($a_pc_id != "")
881  {
882  $path = "//*[@PCID = '$a_pc_id']//".$a_content_tag;
883  $res = xpath_eval($xpc, $path);
884  if (count($res->nodeset) > 0)
885  {
886  return true;
887  }
888  }
889 
890  // fall back to hier id
891  $path = "//*[@HierId = '$a_hier_id']//".$a_content_tag;
892  $res =& xpath_eval($xpc, $path);
893  if (count($res->nodeset) > 0)
894  {
895  return true;
896  }
897  return false;
898  }
899 
900  // only for test purposes
901  function lookforhier($a_hier_id)
902  {
903  $xpc = xpath_new_context($this->dom);
904  $path = "//*[@HierId = '$a_hier_id']";
905  $res =& xpath_eval($xpc, $path);
906  if (count($res->nodeset) == 1)
907  return "YES";
908  else
909  return "NO";
910  }
911 
912 
913  function &getNode()
914  {
915  return $this->node;
916  }
917 
918 
927  function setXMLContent($a_xml, $a_encoding = "UTF-8")
928  {
929  $this->encoding = $a_encoding;
930  $this->xml = $a_xml;
931  }
932 
939  function appendXMLContent($a_xml)
940  {
941  $this->xml.= $a_xml;
942  }
943 
944 
948  function getXMLContent($a_incl_head = false)
949  {
950  // build full http path for XML DOCTYPE header.
951  // Under windows a relative path doesn't work :-(
952  if($a_incl_head)
953  {
954 //echo "+".$this->encoding."+";
955  $enc_str = (!empty($this->encoding))
956  ? "encoding=\"".$this->encoding."\""
957  : "";
958  return "<?xml version=\"1.0\" $enc_str ?>".
959  "<!DOCTYPE PageObject SYSTEM \"".ILIAS_ABSOLUTE_PATH."/xml/".$this->cur_dtd."\">".
960  $this->xml;
961  }
962  else
963  {
964  return $this->xml;
965  }
966  }
967 
972  function copyXmlContent()
973  {
974  $xml = $this->getXmlContent();
975  $temp_dom = domxml_open_mem('<?xml version="1.0" encoding="UTF-8"?>'.$xml,
976  DOMXML_LOAD_PARSING, $error);
977 
978  if(empty($error))
979  {
980  $this->handleCopiedContent($temp_dom);
981  }
982  $xml = $temp_dom->dump_mem(0, $this->encoding);
983  $xml = eregi_replace("<\?xml[^>]*>","",$xml);
984  $xml = eregi_replace("<!DOCTYPE[^>]*>","",$xml);
985 
986  return $xml;
987  }
988 
998  function handleCopiedContent($a_dom, $a_self_ass = true)
999  {
1000  if ($a_self_ass)
1001  {
1002  $this->newQuestionCopies($a_dom);
1003  }
1004  else
1005  {
1006  $this->removeQuestions($a_dom);
1007  }
1008  $this->newIIMCopies($a_dom);
1009  }
1010 
1015  function newIIMCopies($temp_dom)
1016  {
1017  // Get question IDs
1018  $path = "//InteractiveImage/MediaAlias";
1019  $xpc = xpath_new_context($temp_dom);
1020  $res = & xpath_eval($xpc, $path);
1021 
1022  $q_ids = array();
1023  include_once("./Services/COPage/classes/class.ilInternalLink.php");
1024  for ($i = 0; $i < count ($res->nodeset); $i++)
1025  {
1026  $or_id = $res->nodeset[$i]->get_attribute("OriginId");
1027 
1028  $inst_id = ilInternalLink::_extractInstOfTarget($or_id);
1029  $mob_id = ilInternalLink::_extractObjIdOfTarget($or_id);
1030 
1031  if (!($inst_id > 0))
1032  {
1033  if ($mob_id > 0)
1034  {
1035  include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
1036  $media_object = new ilObjMediaObject($mob_id);
1037 
1038  // now copy this question and change reference to
1039  // new question id
1040  $new_mob = $media_object->duplicate();
1041 
1042  $res->nodeset[$i]->set_attribute("OriginId", "il__mob_".$new_mob->getId());
1043  }
1044  }
1045  }
1046  }
1047 
1048 
1053  function newQuestionCopies(&$temp_dom)
1054  {
1055  // Get question IDs
1056  $path = "//Question";
1057  $xpc = xpath_new_context($temp_dom);
1058  $res = & xpath_eval($xpc, $path);
1059 
1060  $q_ids = array();
1061  include_once("./Services/COPage/classes/class.ilInternalLink.php");
1062  for ($i = 0; $i < count ($res->nodeset); $i++)
1063  {
1064  $qref = $res->nodeset[$i]->get_attribute("QRef");
1065 
1066  $inst_id = ilInternalLink::_extractInstOfTarget($qref);
1068 
1069  if (!($inst_id > 0))
1070  {
1071  if ($q_id > 0)
1072  {
1073  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
1074  $question = assQuestion::_instanciateQuestion($q_id);
1075 
1076  // check if page for question exists
1077  // due to a bug in early 4.2.x version this is possible
1078  if (!ilPageObject::_exists("qpl", $q_id))
1079  {
1080  $question->createPageObject();
1081  }
1082 
1083  // now copy this question and change reference to
1084  // new question id
1085  $duplicate_id = $question->duplicate(false);
1086  $res->nodeset[$i]->set_attribute("QRef", "il__qst_".$duplicate_id);
1087  }
1088  }
1089  }
1090  }
1091 
1098  function removeQuestions(&$temp_dom)
1099  {
1100  // Get question IDs
1101  $path = "//Question";
1102  $xpc = xpath_new_context($temp_dom);
1103  $res = & xpath_eval($xpc, $path);
1104  for ($i = 0; $i < count ($res->nodeset); $i++)
1105  {
1106  $parent_node = $res->nodeset[$i]->parent_node();
1107  $parent_node->unlink_node($parent_node);
1108  }
1109  }
1110 
1118  {
1119  // Get question IDs
1120  $this->buildDom();
1121  $path = "//PageContent";
1122  $xpc = xpath_new_context($this->dom);
1123  $res = & xpath_eval($xpc, $path);
1124  return count ($res->nodeset);
1125  }
1126 
1131  function getXMLFromDom($a_incl_head = false, $a_append_mobs = false, $a_append_bib = false,
1132  $a_append_str = "", $a_omit_pageobject_tag = false)
1133  {
1134  if ($a_incl_head)
1135  {
1136 //echo "\n<br>#".$this->encoding."#";
1137  return $this->dom->dump_mem(0, $this->encoding);
1138  }
1139  else
1140  {
1141  // append multimedia object elements
1142  if ($a_append_mobs || $a_append_bib || $a_append_link_info)
1143  {
1144  $mobs = "";
1145  $bibs = "";
1146  if ($a_append_mobs)
1147  {
1148  $mobs =& $this->getMultimediaXML();
1149  }
1150  if ($a_append_bib)
1151  {
1152  $bibs =& $this->getBibliographyXML();
1153  }
1154  $trans =& $this->getLanguageVariablesXML();
1155  return "<dummy>".$this->dom->dump_node($this->node).$mobs.$bibs.$trans.$a_append_str."</dummy>";
1156  }
1157  else
1158  {
1159  if (is_object($this->dom))
1160  {
1161  if ($a_omit_pageobject_tag)
1162  {
1163  $xml = "";
1164  $childs =& $this->node->child_nodes();
1165  for($i = 0; $i < count($childs); $i++)
1166  {
1167  $xml.= $this->dom->dump_node($childs[$i]);
1168  }
1169  return $xml;
1170  }
1171  else
1172  {
1173  $xml = $this->dom->dump_mem(0, $this->encoding);
1174  $xml = eregi_replace("<\?xml[^>]*>","",$xml);
1175  $xml = eregi_replace("<!DOCTYPE[^>]*>","",$xml);
1176 
1177  return $xml;
1178 
1179  // don't use dump_node. This gives always entities.
1180  //return $this->dom->dump_node($this->node);
1181  }
1182  }
1183  else
1184  {
1185  return "";
1186  }
1187  }
1188  }
1189  }
1190 
1195  {
1196  global $lng;
1197 
1198  $xml = "<LVs>";
1199  $lang_vars = array("ed_insert_par", "ed_insert_code",
1200  "ed_insert_dtable", "ed_insert_atable", "ed_insert_media", "ed_insert_list",
1201  "ed_insert_filelist", "ed_paste_clip", "ed_edit", "ed_insert_section",
1202  "ed_edit_prop","ed_edit_files", "ed_edit_data", "ed_delete", "ed_moveafter", "ed_movebefore",
1203  "ed_go", "ed_new_row_after", "ed_new_row_before",
1204  "ed_new_col_after", "ed_new_col_before", "ed_delete_col",
1205  "ed_delete_row", "ed_class", "ed_width", "ed_align_left",
1206  "ed_align_right", "ed_align_center", "ed_align_left_float",
1207  "ed_align_right_float", "ed_delete_item", "ed_new_item_before",
1208  "ed_new_item_after", "ed_copy_clip", "please_select", "ed_split_page",
1209  "ed_item_up", "ed_item_down", "ed_row_up", "ed_row_down",
1210  "ed_col_left", "ed_col_right", "ed_split_page_next","ed_enable",
1211  "de_activate", "ed_insert_repobj", "ed_insert_login_page_element", "ed_insert_map", "ed_insert_tabs",
1212  "ed_insert_pcqst", "empty_question", "ed_paste","question_placeh","media_placeh","text_placeh",
1213  "ed_insert_plach","question_placehl","media_placehl","text_placehl",
1214  "pc_flist", "pc_par", "pc_mob", "pc_qst", "pc_sec", "pc_dtab", "pc_tab",
1215  "pc_code", "pc_vacc", "pc_hacc", "pc_res", "pc_map", "pc_list", "ed_insert_incl", "pc_incl",
1216  "pc_iim", "ed_insert_iim", "pc_prof", "ed_insert_profile", "pc_vrfc",
1217  "ed_insert_verification", "pc_blog", "ed_insert_blog", "ed_edit_multiple", "pc_qover", "ed_insert_qover",
1218  "pc_skills", "ed_insert_skills", "ed_cut", "ed_copy");
1219 
1220  foreach ($lang_vars as $lang_var)
1221  {
1222  $this->appendLangVarXML($xml, $lang_var);
1223  }
1224 
1225  $xml.= "</LVs>";
1226 
1227  return $xml;
1228  }
1229 
1230  function appendLangVarXML(&$xml, $var)
1231  {
1232  global $lng;
1233 
1234  $xml.= "<LV name=\"$var\" value=\"".$lng->txt("cont_".$var)."\"/>";
1235  }
1236 
1238  {
1239  if($this->dom)
1240  {
1241  require_once("./Services/COPage/classes/class.ilPCParagraph.php");
1242  $xpc = xpath_new_context($this->dom);
1243  $path = "//Paragraph[1]";
1244  $res =& xpath_eval($xpc, $path);
1245  if (count($res->nodeset) > 0)
1246  {
1247  $cont_node =& $res->nodeset[0]->parent_node();
1248  $par =& new ilPCParagraph($this->dom);
1249  $par->setNode($cont_node);
1250  return $par->getText();
1251  }
1252  }
1253  return "";
1254  }
1255 
1262  function setParagraphContent($a_hier_id, $a_content)
1263  {
1264  $node = $this->getContentNode($a_hier_id);
1265  if (is_object($node))
1266  {
1267  $node->set_content($a_content);
1268  }
1269  }
1270 
1271 
1280  function setContainsIntLink($a_contains_link)
1281  {
1282  $this->contains_int_link = $a_contains_link;
1283  }
1284 
1289  function containsIntLink()
1290  {
1291  return $this->contains_int_link;
1292  }
1293 
1294  function needsImportParsing($a_parse = "")
1295  {
1296 
1297  if ($a_parse === true)
1298  {
1299  $this->needs_parsing = true;
1300  }
1301  if ($a_parse === false)
1302  {
1303  $this->needs_parsing = false;
1304  }
1305  return $this->needs_parsing;
1306  }
1307 
1313  public function setContainsQuestion($a_val)
1314  {
1315  $this->contains_question = $a_val;
1316  }
1317 
1323  public function getContainsQuestion()
1324  {
1325  return $this->contains_question;
1326  }
1327 
1333  {
1334  global $ilias, $ilDB;
1335 
1336  // todo: access to $_GET and $_POST variables is not
1337  // allowed in non GUI classes!
1338  //
1339  // access to db table object_reference is not allowed here!
1340  $r = $ilias->db->query("SELECT * FROM object_reference WHERE ref_id=".
1341  $ilDB->quote($_GET["ref_id"],'integer'));
1342  $row = $r->fetchRow(DB_FETCHMODE_ASSOC);
1343 
1344  include_once("./classes/class.ilNestedSetXML.php");
1345  $nested = new ilNestedSetXML();
1346  $bibs_xml = $nested->export($row["obj_id"], "bib");
1347 
1348  return $bibs_xml;
1349  }
1350 
1351 
1356  function collectMediaObjects($a_inline_only = true)
1357  {
1358 //echo htmlentities($this->getXMLFromDom());
1359  // determine all media aliases of the page
1360  $xpc = xpath_new_context($this->dom);
1361  $path = "//MediaObject/MediaAlias";
1362  $res =& xpath_eval($xpc, $path);
1363  $mob_ids = array();
1364  for($i = 0; $i < count($res->nodeset); $i++)
1365  {
1366  $id_arr = explode("_", $res->nodeset[$i]->get_attribute("OriginId"));
1367  $mob_id = $id_arr[count($id_arr) - 1];
1368  $mob_ids[$mob_id] = $mob_id;
1369  }
1370 
1371  // determine all media aliases of interactive images
1372  $xpc = xpath_new_context($this->dom);
1373  $path = "//InteractiveImage/MediaAlias";
1374  $res =& xpath_eval($xpc, $path);
1375  for($i = 0; $i < count($res->nodeset); $i++)
1376  {
1377  $id_arr = explode("_", $res->nodeset[$i]->get_attribute("OriginId"));
1378  $mob_id = $id_arr[count($id_arr) - 1];
1379  $mob_ids[$mob_id] = $mob_id;
1380  }
1381 
1382  // determine all inline internal media links
1383  $xpc = xpath_new_context($this->dom);
1384  $path = "//IntLink[@Type = 'MediaObject']";
1385  $res =& xpath_eval($xpc, $path);
1386 
1387  for($i = 0; $i < count($res->nodeset); $i++)
1388  {
1389  if (($res->nodeset[$i]->get_attribute("TargetFrame") == "") ||
1390  (!$a_inline_only))
1391  {
1392  $target = $res->nodeset[$i]->get_attribute("Target");
1393  $id_arr = explode("_", $target);
1394  if (($id_arr[1] == IL_INST_ID) ||
1395  (substr($target, 0, 4) == "il__"))
1396  {
1397  $mob_id = $id_arr[count($id_arr) - 1];
1398  if (ilObject::_exists($mob_id))
1399  {
1400  $mob_ids[$mob_id] = $mob_id;
1401  }
1402  }
1403  }
1404  }
1405 
1406  return $mob_ids;
1407  }
1408 
1409 
1413  function getInternalLinks($a_cnt_multiple = false)
1414  {
1415  // get all internal links of the page
1416  $xpc = xpath_new_context($this->dom);
1417  $path = "//IntLink";
1418  $res =& xpath_eval($xpc, $path);
1419 
1420  $links = array();
1421  $cnt_multiple = 1;
1422  for($i = 0; $i < count($res->nodeset); $i++)
1423  {
1424  $add = "";
1425  if ($a_cnt_multiple)
1426  {
1427  $add = ":".$cnt_multiple;
1428  }
1429  $target = $res->nodeset[$i]->get_attribute("Target");
1430  $type = $res->nodeset[$i]->get_attribute("Type");
1431  $targetframe = $res->nodeset[$i]->get_attribute("TargetFrame");
1432  $anchor = $res->nodeset[$i]->get_attribute("Anchor");
1433  $links[$target.":".$type.":".$targetframe.":".$anchor.$add] =
1434  array("Target" => $target, "Type" => $type,
1435  "TargetFrame" => $targetframe, "Anchor" => $anchor);
1436 
1437  // get links (image map areas) for inline media objects
1438  if ($type == "MediaObject" && $targetframe == "")
1439  {
1440  if (substr($target, 0, 4) =="il__")
1441  {
1442  $id_arr = explode("_", $target);
1443  $id = $id_arr[count($id_arr) - 1];
1444 
1445  $med_links = ilMediaItem::_getMapAreasIntLinks($id);
1446  foreach($med_links as $key => $med_link)
1447  {
1448  $links[$key] = $med_link;
1449  }
1450  }
1451 
1452  }
1453 //echo "<br>-:".$target.":".$type.":".$targetframe.":-";
1454  $cnt_multiple++;
1455  }
1456  unset($xpc);
1457 
1458  // get all media aliases
1459  $xpc = xpath_new_context($this->dom);
1460  $path = "//MediaAlias";
1461  $res =& xpath_eval($xpc, $path);
1462 
1463  require_once("Services/MediaObjects/classes/class.ilMediaItem.php");
1464  for($i = 0; $i < count($res->nodeset); $i++)
1465  {
1466  $oid = $res->nodeset[$i]->get_attribute("OriginId");
1467  if (substr($oid, 0, 4) =="il__")
1468  {
1469  $id_arr = explode("_", $oid);
1470  $id = $id_arr[count($id_arr) - 1];
1471 
1472  $med_links = ilMediaItem::_getMapAreasIntLinks($id);
1473  foreach($med_links as $key => $med_link)
1474  {
1475  $links[$key] = $med_link;
1476  }
1477  }
1478  }
1479  unset($xpc);
1480 
1481  return $links;
1482  }
1483 
1487  function collectFileItems($a_xml = "")
1488  {
1489 //echo "<br>PageObject::collectFileItems[".$this->getId()."]";
1490  // determine all media aliases of the page
1491  if ($a_xml == "")
1492  {
1493  $xpc = xpath_new_context($this->dom);
1494  $doc = $this->dom;
1495  $path = "//FileItem/Identifier";
1496  $res =& xpath_eval($xpc, $path);
1497  }
1498  else
1499  {
1500  $doc = domxml_open_mem($a_xml);
1501  $xpc = xpath_new_context($doc);
1502  $path = "//FileItem/Identifier";
1503  $res =& xpath_eval($xpc, $path);
1504  }
1505  $file_ids = array();
1506  for($i = 0; $i < count($res->nodeset); $i++)
1507  {
1508  $id_arr = explode("_", $res->nodeset[$i]->get_attribute("Entry"));
1509  $file_id = $id_arr[count($id_arr) - 1];
1510  $file_ids[$file_id] = $file_id;
1511  }
1512 
1513  // file items in download links
1514  $xpc = xpath_new_context($doc);
1515  $path = "//IntLink[@Type='File']";
1516  $res =& xpath_eval($xpc, $path);
1517  for($i = 0; $i < count($res->nodeset); $i++)
1518  {
1519  $t = $res->nodeset[$i]->get_attribute("Target");
1520  if (substr($t, 0, 9) == "il__dfile")
1521  {
1522  $id_arr = explode("_", $t);
1523  $file_id = $id_arr[count($id_arr) - 1];
1524  $file_ids[$file_id] = $file_id;
1525  }
1526  }
1527 //var_dump($file_ids); exit;
1528  return $file_ids;
1529  }
1530 
1535  function getMultimediaXML()
1536  {
1537  $mob_ids = $this->collectMediaObjects();
1538 
1539  // get xml of corresponding media objects
1540  $mobs_xml = "";
1541  require_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
1542  foreach($mob_ids as $mob_id => $dummy)
1543  {
1544  if (ilObject::_lookupType($mob_id) == "mob")
1545  {
1546  $mob_obj =& new ilObjMediaObject($mob_id);
1547  $mobs_xml .= $mob_obj->getXML(IL_MODE_OUTPUT);
1548  }
1549  }
1550 //var_dump($mobs_xml);
1551  return $mobs_xml;
1552  }
1553 
1557  function getMediaAliasElement($a_mob_id, $a_nr = 1)
1558  {
1559  $xpc = xpath_new_context($this->dom);
1560  $path = "//MediaObject/MediaAlias[@OriginId='il__mob_$a_mob_id']";
1561  $res =& xpath_eval($xpc, $path);
1562  $mal_node =& $res->nodeset[$a_nr - 1];
1563  $mob_node =& $mal_node->parent_node();
1564 
1565  return $this->dom->dump_node($mob_node);
1566  }
1567 
1573  function validateDom()
1574  {
1575  $this->stripHierIDs();
1576  $this->dom->validate($error);
1577  return $error;
1578  }
1579 
1595  function addHierIDs()
1596  {
1597  $this->hier_ids = array();
1598  $this->first_row_ids = array();
1599  $this->first_col_ids = array();
1600  $this->list_item_ids = array();
1601  $this->file_item_ids = array();
1602 
1603  // set hierarchical ids for Paragraphs, Tables, TableRows and TableData elements
1604  $xpc = xpath_new_context($this->dom);
1605  //$path = "//Paragraph | //Table | //TableRow | //TableData";
1606 
1607  $sep = $path = "";
1608  foreach ($this->id_elements as $el)
1609  {
1610  $path.= $sep."//".$el;
1611  $sep = " | ";
1612  }
1613 
1614  $res =& xpath_eval($xpc, $path);
1615  for($i = 0; $i < count($res->nodeset); $i++)
1616  {
1617  $cnode = $res->nodeset[$i];
1618  $ctag = $cnode->node_name();
1619 
1620  // get hierarchical id of previous sibling
1621  $sib_hier_id = "";
1622  while($cnode =& $cnode->previous_sibling())
1623  {
1624  if (($cnode->node_type() == XML_ELEMENT_NODE)
1625  && $cnode->has_attribute("HierId"))
1626  {
1627  $sib_hier_id = $cnode->get_attribute("HierId");
1628  //$sib_hier_id = $id_attr->value();
1629  break;
1630  }
1631  }
1632 
1633  if ($sib_hier_id != "") // set id to sibling id "+ 1"
1634  {
1635  require_once("./Services/COPage/classes/class.ilPageContent.php");
1636  $node_hier_id = ilPageContent::incEdId($sib_hier_id);
1637  $res->nodeset[$i]->set_attribute("HierId", $node_hier_id);
1638  $this->hier_ids[] = $node_hier_id;
1639  if ($ctag == "TableData")
1640  {
1641  if (substr($par_hier_id,strlen($par_hier_id)-2) == "_1")
1642  {
1643  $this->first_row_ids[] = $node_hier_id;
1644  }
1645  }
1646  if ($ctag == "ListItem")
1647  {
1648  $this->list_item_ids[] = $node_hier_id;
1649  }
1650  if ($ctag == "FileItem")
1651  {
1652  $this->file_item_ids[] = $node_hier_id;
1653  }
1654  }
1655  else // no sibling -> node is first child
1656  {
1657  // get hierarchical id of next parent
1658  $cnode = $res->nodeset[$i];
1659  $par_hier_id = "";
1660  while($cnode =& $cnode->parent_node())
1661  {
1662  if (($cnode->node_type() == XML_ELEMENT_NODE)
1663  && $cnode->has_attribute("HierId"))
1664  {
1665  $par_hier_id = $cnode->get_attribute("HierId");
1666  //$par_hier_id = $id_attr->value();
1667  break;
1668  }
1669  }
1670 //echo "<br>par:".$par_hier_id." ($ctag)";
1671  if (($par_hier_id != "") && ($par_hier_id != "pg")) // set id to parent_id."_1"
1672  {
1673  $node_hier_id = $par_hier_id."_1";
1674  $res->nodeset[$i]->set_attribute("HierId", $node_hier_id);
1675  $this->hier_ids[] = $node_hier_id;
1676  if ($ctag == "TableData")
1677  {
1678  $this->first_col_ids[] = $node_hier_id;
1679  if (substr($par_hier_id,strlen($par_hier_id)-2) == "_1")
1680  {
1681  $this->first_row_ids[] = $node_hier_id;
1682  }
1683  }
1684  if ($ctag == "ListItem")
1685  {
1686  $this->list_item_ids[] = $node_hier_id;
1687  }
1688  if ($ctag == "FileItem")
1689  {
1690  $this->file_item_ids[] = $node_hier_id;
1691  }
1692 
1693  }
1694  else // no sibling, no parent -> first node
1695  {
1696  $node_hier_id = "1";
1697  $res->nodeset[$i]->set_attribute("HierId", $node_hier_id);
1698  $this->hier_ids[] = $node_hier_id;
1699  }
1700  }
1701  }
1702 
1703  // set special hierarchical id "pg" for pageobject
1704  $xpc = xpath_new_context($this->dom);
1705  $path = "//PageObject";
1706  $res =& xpath_eval($xpc, $path);
1707  for($i = 0; $i < count($res->nodeset); $i++) // should only be 1
1708  {
1709  $res->nodeset[$i]->set_attribute("HierId", "pg");
1710  $this->hier_ids[] = "pg";
1711  }
1712  unset($xpc);
1713  }
1714 
1718  function getHierIds()
1719  {
1720  return $this->hier_ids;
1721  }
1722 
1726  function getFirstRowIds()
1727  {
1728  return $this->first_row_ids;
1729  }
1730 
1735  {
1736  return $this->first_col_ids;
1737  }
1738 
1742  function getListItemIds()
1743  {
1744  return $this->list_item_ids;
1745  }
1746 
1750  function getFileItemIds()
1751  {
1752  return $this->file_item_ids;
1753  }
1754 
1758  function stripHierIDs()
1759  {
1760  if(is_object($this->dom))
1761  {
1762  $xpc = xpath_new_context($this->dom);
1763  $path = "//*[@HierId]";
1764  $res =& xpath_eval($xpc, $path);
1765  for($i = 0; $i < count($res->nodeset); $i++) // should only be 1
1766  {
1767  if ($res->nodeset[$i]->has_attribute("HierId"))
1768  {
1769  $res->nodeset[$i]->remove_attribute("HierId");
1770  }
1771  }
1772  unset($xpc);
1773  }
1774  }
1775 
1779  function getHierIdsForPCIds($a_pc_ids)
1780  {
1781  if (!is_array($a_pc_ids) || count($a_pc_ids) == 0)
1782  {
1783  return array();
1784  }
1785  $ret = array();
1786 
1787  if(is_object($this->dom))
1788  {
1789  $xpc = xpath_new_context($this->dom);
1790  $path = "//*[@PCID]";
1791  $res =& xpath_eval($xpc, $path);
1792  for($i = 0; $i < count($res->nodeset); $i++) // should only be 1
1793  {
1794  $pc_id = $res->nodeset[$i]->get_attribute("PCID");
1795  if (in_array($pc_id, $a_pc_ids))
1796  {
1797  $ret[$pc_id] = $res->nodeset[$i]->get_attribute("HierId");
1798  }
1799  }
1800  unset($xpc);
1801  }
1802 //var_dump($ret);
1803  return $ret;
1804  }
1805 
1809  function addFileSizes()
1810  {
1811  $xpc = xpath_new_context($this->dom);
1812  $path = "//FileItem";
1813  $res =& xpath_eval($xpc, $path);
1814  for($i = 0; $i < count($res->nodeset); $i++)
1815  {
1816  $cnode =& $res->nodeset[$i];
1817  $size_node =& $this->dom->create_element("Size");
1818  $size_node =& $cnode->append_child($size_node);
1819 
1820  $childs =& $cnode->child_nodes();
1821  $size = "";
1822  for($j = 0; $j < count($childs); $j++)
1823  {
1824  if ($childs[$j]->node_name() == "Identifier")
1825  {
1826  if ($childs[$j]->has_attribute("Entry"))
1827  {
1828  $entry = $childs[$j]->get_attribute("Entry");
1829  $entry_arr = explode("_", $entry);
1830  $id = $entry_arr[count($entry_arr) - 1];
1831  require_once("./Modules/File/classes/class.ilObjFile.php");
1833  }
1834  }
1835  }
1836  $size_node->set_content($size);
1837  }
1838 
1839  unset($xpc);
1840  }
1841 
1846  function resolveIntLinks()
1847  {
1848  // resolve normal internal links
1849  $xpc = xpath_new_context($this->dom);
1850  $path = "//IntLink";
1851  $res =& xpath_eval($xpc, $path);
1852  for($i = 0; $i < count($res->nodeset); $i++)
1853  {
1854  $target = $res->nodeset[$i]->get_attribute("Target");
1855  $type = $res->nodeset[$i]->get_attribute("Type");
1856 
1857  $new_target = ilInternalLink::_getIdForImportId($type, $target);
1858  if ($new_target !== false)
1859  {
1860  $res->nodeset[$i]->set_attribute("Target", $new_target);
1861  }
1862  else // check wether link target is same installation
1863  {
1864  if (ilInternalLink::_extractInstOfTarget($target) == IL_INST_ID &&
1865  IL_INST_ID > 0 && $type != "RepositoryItem")
1866  {
1867  $new_target = ilInternalLink::_removeInstFromTarget($target);
1868  if (ilInternalLink::_exists($type, $new_target))
1869  {
1870  $res->nodeset[$i]->set_attribute("Target", $new_target);
1871  }
1872  }
1873  }
1874 
1875  }
1876  unset($xpc);
1877 
1878  // resolve internal links in map areas
1879  $xpc = xpath_new_context($this->dom);
1880  $path = "//MediaAlias";
1881  $res =& xpath_eval($xpc, $path);
1882 //echo "<br><b>page::resolve</b><br>";
1883 //echo "Content:".htmlentities($this->getXMLFromDOM()).":<br>";
1884  for($i = 0; $i < count($res->nodeset); $i++)
1885  {
1886  $orig_id = $res->nodeset[$i]->get_attribute("OriginId");
1887  $id_arr = explode("_", $orig_id);
1888  $mob_id = $id_arr[count($id_arr) - 1];
1890  }
1891  }
1892 
1899  function resolveMediaAliases($a_mapping)
1900  {
1901  // resolve normal internal links
1902  $xpc = xpath_new_context($this->dom);
1903  $path = "//MediaAlias";
1904  $res =& xpath_eval($xpc, $path);
1905  $changed = false;
1906  for($i = 0; $i < count($res->nodeset); $i++)
1907  {
1908  $old_id = $res->nodeset[$i]->get_attribute("OriginId");
1909  $old_id = explode("_", $old_id);
1910  $old_id = $old_id[count($old_id) - 1];
1911  if ($a_mapping[$old_id] > 0)
1912  {
1913  $res->nodeset[$i]->set_attribute("OriginId", "il__mob_".$a_mapping[$old_id]);
1914  $changed = true;
1915  }
1916  }
1917  unset($xpc);
1918 
1919  return $changed;
1920  }
1921 
1928  function resolveIIMMediaAliases($a_mapping)
1929  {
1930  // resolve normal internal links
1931  $xpc = xpath_new_context($this->dom);
1932  $path = "//InteractiveImage/MediaAlias";
1933  $res =& xpath_eval($xpc, $path);
1934  $changed = false;
1935  for($i = 0; $i < count($res->nodeset); $i++)
1936  {
1937  $old_id = $res->nodeset[$i]->get_attribute("OriginId");
1938  if ($a_mapping[$old_id] > 0)
1939  {
1940  $res->nodeset[$i]->set_attribute("OriginId", "il__mob_".$a_mapping[$old_id]);
1941  $changed = true;
1942  }
1943  }
1944  unset($xpc);
1945 
1946  return $changed;
1947  }
1948 
1955  function resolveFileItems($a_mapping)
1956  {
1957  // resolve normal internal links
1958  $xpc = xpath_new_context($this->dom);
1959  $path = "//FileItem/Identifier";
1960  $res =& xpath_eval($xpc, $path);
1961  $changed = false;
1962  for($i = 0; $i < count($res->nodeset); $i++)
1963  {
1964  $old_id = $res->nodeset[$i]->get_attribute("Entry");
1965  $old_id = explode("_", $old_id);
1966  $old_id = $old_id[count($old_id) - 1];
1967  if ($a_mapping[$old_id] > 0)
1968  {
1969  $res->nodeset[$i]->set_attribute("Entry", "il__file_".$a_mapping[$old_id]);
1970  $changed = true;
1971  }
1972  }
1973  unset($xpc);
1974 
1975  return $changed;
1976  }
1977 
1982  function resolveQuestionReferences($a_mapping)
1983  {
1984  // resolve normal internal links
1985  $xpc = xpath_new_context($this->dom);
1986  $path = "//Question";
1987  $res =& xpath_eval($xpc, $path);
1988  for($i = 0; $i < count($res->nodeset); $i++)
1989  {
1990  $qref = $res->nodeset[$i]->get_attribute("QRef");
1991 
1992  if (isset($a_mapping[$qref]))
1993  {
1994  $res->nodeset[$i]->set_attribute("QRef", "il__qst_".$a_mapping[$qref]["pool"]);
1995  }
1996  }
1997  unset($xpc);
1998  }
1999 
2000 
2007  function moveIntLinks($a_from_to)
2008  {
2009  $this->buildDom();
2010 
2011  $changed = false;
2012 
2013  // resolve normal internal links
2014  $xpc = xpath_new_context($this->dom);
2015  $path = "//IntLink";
2016  $res =& xpath_eval($xpc, $path);
2017  for($i = 0; $i < count($res->nodeset); $i++)
2018  {
2019  $target = $res->nodeset[$i]->get_attribute("Target");
2020  $type = $res->nodeset[$i]->get_attribute("Type");
2021  $obj_id = ilInternalLink::_extractObjIdOfTarget($target);
2022  if ($a_from_to[$obj_id] > 0 && is_int(strpos($target, "__")))
2023  {
2024  if ($type == "PageObject" && ilLMObject::_lookupType($a_from_to[$obj_id]) == "pg")
2025  {
2026  $res->nodeset[$i]->set_attribute("Target", "il__pg_".$a_from_to[$obj_id]);
2027  $changed = true;
2028  }
2029  if ($type == "StructureObject" && ilLMObject::_lookupType($a_from_to[$obj_id]) == "st")
2030  {
2031  $res->nodeset[$i]->set_attribute("Target", "il__st_".$a_from_to[$obj_id]);
2032  $changed = true;
2033  }
2034  }
2035  }
2036  unset($xpc);
2037 
2038  // map areas
2039  $this->addHierIDs();
2040  $xpc = xpath_new_context($this->dom);
2041  $path = "//MediaAlias";
2042  $res =& xpath_eval($xpc, $path);
2043 
2044  require_once("Services/MediaObjects/classes/class.ilMediaItem.php");
2045  require_once("Services/COPage/classes/class.ilMediaAliasItem.php");
2046 
2047  for($i = 0; $i < count($res->nodeset); $i++)
2048  {
2049  $media_object_node = $res->nodeset[$i]->parent_node();
2050  $page_content_node = $media_object_node->parent_node();
2051  $c_hier_id = $page_content_node->get_attribute("HierId");
2052 
2053  // first check, wheter we got instance map areas -> take these
2054  $std_alias_item = new ilMediaAliasItem($this->dom,
2055  $c_hier_id, "Standard");
2056  $areas = $std_alias_item->getMapAreas();
2057  $correction_needed = false;
2058  if (count($areas) > 0)
2059  {
2060  // check if correction needed
2061  foreach($areas as $area)
2062  {
2063  if ($area["Type"] == "PageObject" ||
2064  $area["Type"] == "StructureObject")
2065  {
2066  $t = $area["Target"];
2067  $tid = _extractObjIdOfTarget($t);
2068  if ($a_from_to[$tid] > 0)
2069  {
2070  $correction_needed = true;
2071  }
2072  }
2073  }
2074  }
2075  else
2076  {
2077  $areas = array();
2078 
2079  // get object map areas and check whether at least one must
2080  // be corrected
2081  $oid = $res->nodeset[$i]->get_attribute("OriginId");
2082  if (substr($oid, 0, 4) =="il__")
2083  {
2084  $id_arr = explode("_", $oid);
2085  $id = $id_arr[count($id_arr) - 1];
2086 
2087  $mob = new ilObjMediaObject($id);
2088  $med_item = $mob->getMediaItem("Standard");
2089  $med_areas = $med_item->getMapAreas();
2090 
2091  foreach($med_areas as $area)
2092  {
2093  $link_type = ($area->getLinkType() == "int")
2094  ? "IntLink"
2095  : "ExtLink";
2096 
2097  $areas[] = array(
2098  "Nr" => $area->getNr(),
2099  "Shape" => $area->getShape(),
2100  "Coords" => $area->getCoords(),
2101  "Link" => array(
2102  "LinkType" => $link_type,
2103  "Href" => $area->getHref(),
2104  "Title" => $area->getTitle(),
2105  "Target" => $area->getTarget(),
2106  "Type" => $area->getType(),
2107  "TargetFrame" => $area->getTargetFrame()
2108  )
2109  );
2110 
2111  if ($area->getType() == "PageObject" ||
2112  $area->getType() == "StructureObject")
2113  {
2114  $t = $area->getTarget();
2116  if ($a_from_to[$tid] > 0)
2117  {
2118  $correction_needed = true;
2119  }
2120 //var_dump($a_from_to);
2121  }
2122  }
2123  }
2124  }
2125 
2126  // correct map area links
2127  if ($correction_needed)
2128  {
2129  $changed = true;
2130  $std_alias_item->deleteAllMapAreas();
2131  foreach($areas as $area)
2132  {
2133  if ($area["Link"]["LinkType"] == "IntLink")
2134  {
2135  $target = $area["Link"]["Target"];
2136  $type = $area["Link"]["Type"];
2137  $obj_id = ilInternalLink::_extractObjIdOfTarget($target);
2138  if ($a_from_to[$obj_id] > 0)
2139  {
2140  if ($type == "PageObject" && ilLMObject::_lookupType($a_from_to[$obj_id]) == "pg")
2141  {
2142  $area["Link"]["Target"] = "il__pg_".$a_from_to[$obj_id];
2143  }
2144  if ($type == "StructureObject" && ilLMObject::_lookupType($a_from_to[$obj_id]) == "st")
2145  {
2146  $area["Link"]["Target"] = "il__st_".$a_from_to[$obj_id];
2147  }
2148  }
2149  }
2150 
2151  $std_alias_item->addMapArea($area["Shape"], $area["Coords"],
2152  $area["Link"]["Title"],
2153  array( "Type" => $area["Link"]["Type"],
2154  "TargetFrame" => $area["Link"]["TargetFrame"],
2155  "Target" => $area["Link"]["Target"],
2156  "Href" => $area["Link"]["Href"],
2157  "LinkType" => $area["Link"]["LinkType"],
2158  ));
2159  }
2160  }
2161  }
2162  unset($xpc);
2163 
2164  return $changed;
2165  }
2166 
2172  static function _handleImportRepositoryLinks($a_rep_import_id, $a_rep_type, $a_rep_ref_id)
2173  {
2174  include_once("./Services/COPage/classes/class.ilInternalLink.php");
2175 
2176 //echo "-".$a_rep_import_id."-".$a_rep_ref_id."-";
2177  $sources = ilInternalLink::_getSourcesOfTarget("obj",
2178  ilInternalLink::_extractObjIdOfTarget($a_rep_import_id),
2179  ilInternalLink::_extractInstOfTarget($a_rep_import_id));
2180 //var_dump($sources);
2181  foreach($sources as $source)
2182  {
2183 //echo "A";
2184  if ($source["type"] == "lm:pg")
2185  {
2186 //echo "B";
2187  $page_obj = new ilPageObject("lm", $source["id"], false);
2188  if (!$page_obj->page_not_found)
2189  {
2190 //echo "C";
2191  $page_obj->handleImportRepositoryLink($a_rep_import_id,
2192  $a_rep_type, $a_rep_ref_id);
2193  }
2194  $page_obj->update();
2195  }
2196  }
2197  }
2198 
2199  function handleImportRepositoryLink($a_rep_import_id, $a_rep_type, $a_rep_ref_id)
2200  {
2201  $this->buildDom();
2202 
2203  // resolve normal internal links
2204  $xpc = xpath_new_context($this->dom);
2205  $path = "//IntLink";
2206  $res =& xpath_eval($xpc, $path);
2207 //echo "1";
2208  for($i = 0; $i < count($res->nodeset); $i++)
2209  {
2210 //echo "2";
2211  $target = $res->nodeset[$i]->get_attribute("Target");
2212  $type = $res->nodeset[$i]->get_attribute("Type");
2213  if ($target == $a_rep_import_id && $type == "RepositoryItem")
2214  {
2215 //echo "setting:"."il__".$a_rep_type."_".$a_rep_ref_id;
2216  $res->nodeset[$i]->set_attribute("Target",
2217  "il__".$a_rep_type."_".$a_rep_ref_id);
2218  }
2219  }
2220  unset($xpc);
2221  }
2222 
2226  function createFromXML()
2227  {
2228  global $lng, $ilDB, $ilUser;
2229 
2230 //echo "<br>PageObject::createFromXML[".$this->getId()."]";
2231 
2232  if($this->getXMLContent() == "")
2233  {
2234  $this->setXMLContent("<PageObject></PageObject>");
2235  }
2236 
2237  $iel = $this->containsDeactivatedElements($this->getXMLContent());
2238  $inl = $this->containsIntLinks($this->getXMLContent());
2239 
2240  // create object
2241  /* $query = "INSERT INTO page_object (page_id, parent_id, content, parent_type, create_user, last_change_user, inactive_elements, int_links, created, last_change) VALUES ".
2242  "(".$ilDB->quote($this->getId()).",".
2243  $ilDB->quote($this->getParentId()).",".
2244  $ilDB->quote($this->getXMLContent()).
2245  ", ".$ilDB->quote($this->getParentType()).
2246  ", ".$ilDB->quote($ilUser->getId()).
2247  ", ".$ilDB->quote($ilUser->getId()).
2248  ", ".$ilDB->quote($iel, "integer")." ".
2249  ", ".$ilDB->quote($inl, "integer")." ".
2250  ", now(), now())"; */
2251 
2252  $ilDB->insert("page_object", array(
2253  "page_id" => array("integer", $this->getId()),
2254  "parent_id" => array("integer", $this->getParentId()),
2255  "content" => array("clob", $this->getXMLContent()),
2256  "parent_type" => array("text", $this->getParentType()),
2257  "create_user" => array("integer", $ilUser->getId()),
2258  "last_change_user" => array("integer", $ilUser->getId()),
2259  "active" => array("integer", $this->getActive()),
2260  "inactive_elements" => array("integer", $iel),
2261  "int_links" => array("integer", $inl),
2262  "created" => array("timestamp", ilUtil::now()),
2263  "last_change" => array("timestamp", ilUtil::now())
2264  ));
2265 
2266 // todo: put this into insert
2267 /* if(!$ilDB->checkQuerySize($query))
2268  {
2269  $this->ilias->raiseError($lng->txt("check_max_allowed_packet_size"),$this->ilias->error_obj->MESSAGE);
2270  return false;
2271  }*/
2272 
2273 // $ilDB->query($query);
2274  }
2275 
2276 
2280  function updateFromXML()
2281  {
2282  global $lng, $ilDB, $ilUser;
2283 
2284 //echo "<br>PageObject::updateFromXML[".$this->getId()."]";
2285 //echo "update:".ilUtil::prepareDBString(($this->getXMLContent())).":<br>";
2286 //echo "update:".htmlentities($this->getXMLContent()).":<br>";
2287 
2288  $iel = $this->containsDeactivatedElements($this->getXMLContent());
2289  $inl = $this->containsIntLinks($this->getXMLContent());
2290 
2291  /*$query = "UPDATE page_object ".
2292  "SET content = ".$ilDB->quote($this->getXMLContent())." ".
2293  ", parent_id = ".$ilDB->quote($this->getParentId())." ".
2294  ", last_change_user = ".$ilDB->quote($ilUser->getId())." ".
2295  ", last_change = now() ".
2296  ", active = ".$ilDB->quote($this->getActive())." ".
2297  ", activation_start = ".$ilDB->quote($this->getActivationStart())." ".
2298  ", activation_end = ".$ilDB->quote($this->getActivationEnd())." ".
2299  ", inactive_elements = ".$ilDB->quote($iel, "integer")." ".
2300  ", int_links = ".$ilDB->quote($inl, "integer")." ".
2301  "WHERE page_id = ".$ilDB->quote($this->getId())." AND parent_type=".
2302  $ilDB->quote($this->getParentType());*/
2303 
2304  $ilDB->update("page_object", array(
2305  "content" => array("clob", $this->getXMLContent()),
2306  "parent_id" => array("integer", $this->getParentId()),
2307  "last_change_user" => array("integer", $ilUser->getId()),
2308  "last_change" => array("timestamp", ilUtil::now()),
2309  "active" => array("integer", $this->getActive()),
2310  "activation_start" => array("timestamp", $this->getActivationStart()),
2311  "activation_end" => array("timestamp", $this->getActivationEnd()),
2312  "inactive_elements" => array("integer", $iel),
2313  "int_links" => array("integer", $inl),
2314  ), array(
2315  "page_id" => array("integer", $this->getId()),
2316  "parent_type" => array("text", $this->getParentType())
2317  ));
2318 
2319 // todo: move this to update
2320 /* if(!$ilDB->checkQuerySize($query))
2321  {
2322  $this->ilias->raiseError($lng->txt("check_max_allowed_packet_size"),$this->ilias->error_obj->MESSAGE);
2323  return false;
2324  }
2325  $ilDB->query($query);*/
2326 // save style usage
2327  $this->saveStyleUsage($this->getXMLContent());
2328 
2329  // save internal link information
2330  $this->saveInternalLinks($this->getXMLContent());
2331  return true;
2332  }
2333 
2337  function update($a_validate = true, $a_no_history = false, $skip_handle_usages = false)
2338  {
2339  global $lng, $ilDB, $ilUser, $ilLog, $ilCtrl;
2340 
2341  $lm_set = new ilSetting("lm");
2342 
2343 //echo "<br>**".$this->getId()."**";
2344 //echo "<br>PageObject::update[".$this->getId()."],validate($a_validate)";
2345 //echo "\n<br>dump_all2:".$this->dom->dump_mem(0, "UTF-8").":";
2346 //echo "\n<br>PageObject::update:".$this->getXMLFromDom().":";
2347 //echo "<br>PageObject::update:".htmlentities($this->getXMLFromDom());
2348 
2349  // add missing pc ids
2350  if (!$this->checkPCIds())
2351  {
2352  $this->insertPCIds();
2353  }
2354 
2355  // test validating
2356  if($a_validate)
2357  {
2358  $errors = $this->validateDom();
2359  }
2360 
2361 //echo "-".htmlentities($this->getXMLFromDom())."-"; exit;
2362  if(empty($errors))
2363  {
2365 
2366  $content = $this->getXMLFromDom();
2367  // this needs to be locked
2368 
2369  // write history entry
2370  $old_set = $ilDB->query("SELECT * FROM page_object WHERE ".
2371  "page_id = ".$ilDB->quote($this->getId(), "integer")." AND ".
2372  "parent_type = ".$ilDB->quote($this->getParentType(), "text"));
2373  $last_nr_set = $ilDB->query("SELECT max(nr) as mnr FROM page_history WHERE ".
2374  "page_id = ".$ilDB->quote($this->getId(), "integer")." AND ".
2375  "parent_type = ".$ilDB->quote($this->getParentType(), "text"));
2376  $last_nr = $ilDB->fetchAssoc($last_nr_set);
2377  if ($old_rec = $ilDB->fetchAssoc($old_set))
2378  {
2379  // only save, if something has changed and not in layout mode
2380  if (($content != $old_rec["content"]) && !$a_no_history &&
2381  !$this->history_saved && !$this->layout_mode &&
2382  $lm_set->get("page_history", 1))
2383  {
2384  if ($old_rec["content"] != "<PageObject></PageObject>")
2385  {
2386  $ilDB->manipulateF("DELETE FROM page_history WHERE ".
2387  "page_id = %s AND parent_type = %s AND hdate = %s",
2388  array("integer", "text", "timestamp"),
2389  array($old_rec["page_id"], $old_rec["parent_type"], $old_rec["last_change"]));
2390 
2391  // the following lines are a workaround for
2392  // bug 6741
2393  $last_c = $old_rec["last_change"];
2394  if ($last_c == "")
2395  {
2396  $last_c = ilUtil::now();
2397  }
2398 
2399  $ilDB->insert("page_history", array(
2400  "page_id" => array("integer", $old_rec["page_id"]),
2401  "parent_type" => array("text", $old_rec["parent_type"]),
2402  "hdate" => array("timestamp", $last_c),
2403  "parent_id" => array("integer", $old_rec["parent_id"]),
2404  "content" => array("clob", $old_rec["content"]),
2405  "user_id" => array("integer", $old_rec["last_change_user"]),
2406  "ilias_version" => array("text", ILIAS_VERSION_NUMERIC),
2407  "nr" => array("integer", (int) $last_nr["mnr"] + 1)
2408  ));
2409  /*$h_query = "REPLACE INTO page_history ".
2410  "(page_id, parent_type, hdate, parent_id, content, user_id, ilias_version, nr) VALUES (".
2411  $ilDB->quote($old_rec["page_id"]).",".
2412  $ilDB->quote($old_rec["parent_type"]).",".
2413  $ilDB->quote($old_rec["last_change"]).",".
2414  $ilDB->quote($old_rec["parent_id"]).",".
2415  $ilDB->quote($old_rec["content"]).",".
2416  $ilDB->quote($old_rec["last_change_user"]).",".
2417  $ilDB->quote(ILIAS_VERSION_NUMERIC).",".
2418  $ilDB->quote($last_nr["mnr"] + 1).")";
2419 //echo "<br><br>+$a_no_history+$h_query";
2420  $ilDB->query($h_query);*/
2421  $this->saveMobUsage($old_rec["content"], $last_nr["mnr"] + 1);
2422  $this->saveStyleUsage($old_rec["content"], $last_nr["mnr"] + 1);
2423  $this->saveFileUsage($old_rec["content"], $last_nr["mnr"] + 1);
2424  $this->saveContentIncludeUsage($old_rec["content"], $last_nr["mnr"] + 1);
2425  $this->saveSkillUsage($old_rec["content"], $last_nr["mnr"] + 1);
2426  $this->history_saved = true; // only save one time
2427  }
2428  else
2429  {
2430  $this->history_saved = true; // do not save on first change
2431  }
2432  }
2433  }
2434 //echo htmlentities($content);
2435  $em = (trim($content) == "<PageObject/>")
2436  ? 1
2437  : 0;
2438 
2439  $iel = $this->containsDeactivatedElements($content);
2440  $inl = $this->containsIntLinks($content);
2441  /*$query = "UPDATE page_object ".
2442  "SET content = ".$ilDB->quote($content)." ".
2443  ", parent_id= ".$ilDB->quote($this->getParentId())." ".
2444  ", last_change_user= ".$ilDB->quote($ilUser->getId())." ".
2445  ", last_change = now() ".
2446  ", is_empty = ".$ilDB->quote($em, "integer")." ".
2447  ", active = ".$ilDB->quote($this->getActive())." ".
2448  ", activation_start = ".$ilDB->quote($this->getActivationStart())." ".
2449  ", activation_end = ".$ilDB->quote($this->getActivationEnd())." ".
2450  ", inactive_elements = ".$ilDB->quote($iel, "integer")." ".
2451  ", int_links = ".$ilDB->quote($inl, "integer")." ".
2452  " WHERE page_id = ".$ilDB->quote($this->getId()).
2453  " AND parent_type= ".$ilDB->quote($this->getParentType());*/
2454 
2455  $ilDB->update("page_object", array(
2456  "content" => array("clob", $content),
2457  "parent_id" => array("integer", $this->getParentId()),
2458  "last_change_user" => array("integer", $ilUser->getId()),
2459  "last_change" => array("timestamp", ilUtil::now()),
2460  "is_empty" => array("integer", $em),
2461  "active" => array("integer", $this->getActive()),
2462  "activation_start" => array("timestamp", $this->getActivationStart()),
2463  "activation_end" => array("timestamp", $this->getActivationEnd()),
2464  "inactive_elements" => array("integer", $iel),
2465  "int_links" => array("integer", $inl),
2466  ), array(
2467  "page_id" => array("integer", $this->getId()),
2468  "parent_type" => array("text", $this->getParentType())
2469  ));
2470 
2471 // todo put this into update function
2472 /* if(!$this->ilias->db->checkQuerySize($query))
2473  {
2474  $this->ilias->raiseError($lng->txt("check_max_allowed_packet_size"),$this->ilias->error_obj->MESSAGE);
2475  return false;
2476  }*/
2477 
2478 // $this->ilias->db->query($query);
2479 
2480  if (!$skip_handle_usages)
2481  {
2482  // handle media object usage
2483  include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
2485  $this->getParentType().":pg", $this->getId());
2486  $this->saveMobUsage($this->getXMLFromDom());
2487  $this->saveMetaKeywords($this->getXMLFromDom());
2488  foreach($mob_ids as $mob) // check, whether media object can be deleted
2489  {
2490  if (ilObject::_exists($mob) && ilObject::_lookupType($mob) == "mob")
2491  {
2492  $mob_obj = new ilObjMediaObject($mob);
2493  $usages = $mob_obj->getUsages(false);
2494  if (count($usages) == 0) // delete, if no usage exists
2495  {
2496  $mob_obj->delete();
2497  }
2498  }
2499  }
2500 
2501  // handle file usages
2502  include_once("./Modules/File/classes/class.ilObjFile.php");
2503  $file_ids = ilObjFile::_getFilesOfObject(
2504  $this->getParentType().":pg", $this->getId());
2505  $this->saveFileUsage();
2506  foreach($file_ids as $file) // check, whether file object can be deleted
2507  {
2508  if (ilObject::_exists($file))
2509  {
2510  $file_obj = new ilObjFile($file, false);
2511  $usages = $file_obj->getUsages();
2512  if (count($usages) == 0) // delete, if no usage exists
2513  {
2514  if ($file_obj->getMode() == "filelist") // non-repository object
2515  {
2516  $file_obj->delete();
2517  }
2518  }
2519  }
2520  }
2521 
2522  // save style usage
2523  $this->saveStyleUsage($this->getXMLFromDom());
2524 
2525  // save content include usage
2526  $this->saveContentIncludeUsage($this->getXMLFromDom());
2527  $this->saveSkillUsage($this->getXMLFromDom());
2528  }
2529 
2530  // save internal link information
2531  $this->saveInternalLinks($this->getXMLFromDom());
2532  $this->saveAnchors($this->getXMLFromDom());
2533  $this->callUpdateListeners();
2534 //echo "<br>PageObject::update:".htmlentities($this->getXMLContent()).":";
2535  return true;
2536  }
2537  else
2538  {
2539  return $errors;
2540  }
2541  }
2542 
2543 
2547  function delete()
2548  {
2549  global $ilDB;
2550 
2551  $mobs = array();
2552  $files = array();
2553 
2554  if (!$this->page_not_found)
2555  {
2556  $this->buildDom();
2557  $mobs = $this->collectMediaObjects(false);
2558  $files = $this->collectFileItems();
2559  }
2560 
2561  // delete mob usages
2562  $this->saveMobUsage("<dummy></dummy>");
2563 
2564  // delete style usages
2565  $this->saveStyleUsage("<dummy></dummy>");
2566 
2567  // delete style usages
2568  $this->saveContentIncludeUsage("<dummy></dummy>");
2569  $this->saveSkillUsage("<dummy></dummy>");
2570 
2571  // delete internal links
2572  $this->saveInternalLinks("<dummy></dummy>");
2573 
2574  // delete anchors
2575  $this->saveAnchors("<dummy></dummy>");
2576 
2577  // delete all file usages
2578  include_once("./Modules/File/classes/class.ilObjFile.php");
2579  ilObjFile::_deleteAllUsages($this->getParentType().":pg", $this->getId());
2580 
2581  // delete news
2582  include_once("./Services/News/classes/class.ilNewsItem.php");
2584  $this->getParentType(), $this->getId(), "pg");
2585 
2586  // delete page_object entry
2587  $ilDB->manipulate("DELETE FROM page_object ".
2588  "WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
2589  " AND parent_type= ".$ilDB->quote($this->getParentType(), "text"));
2590  //$this->ilias->db->query($query);
2591 
2592  // delete media objects
2593  foreach ($mobs as $mob_id)
2594  {
2595  if(ilObject::_lookupType($mob_id) != 'mob')
2596  {
2597  $GLOBALS['ilLog']->write(__METHOD__.': Type mismatch. Ignoring mob with id: '.$mob_id);
2598  continue;
2599  }
2600 
2601  if (ilObject::_exists($mob_id))
2602  {
2603  $mob_obj =& new ilObjMediaObject($mob_id);
2604  $mob_obj->delete();
2605  }
2606  }
2607 
2608  include_once("./Modules/File/classes/class.ilObjFile.php");
2609  foreach ($files as $file_id)
2610  {
2611  if (ilObject::_exists($file_id))
2612  {
2613  $file_obj =& new ilObjFile($file_id, false);
2614  $file_obj->delete();
2615  }
2616  }
2617 
2618  /* delete public and private notes (see PageObjectGUI->getNotesHTML())
2619  as they can be seen as personal data we are keeping them for now
2620  include_once("Services/Notes/classes/class.ilNote.php");
2621  foreach(array(IL_NOTE_PRIVATE, IL_NOTE_PUBLIC) as $note_type)
2622  {
2623  foreach(ilNote::_getNotesOfObject($this->getParentId(), $this->getId(),
2624  $this->getParentType(), $note_type) as $note)
2625  {
2626  $note->delete();
2627  }
2628  }
2629  */
2630  }
2631 
2637  function saveMetaKeywords($a_xml)
2638  {
2639  // not nice, should be set by context per method
2640  if ($this->getParentType() == "gdf" ||
2641  $this->getParentType() == "lm" ||
2642  $this->getParentType() == "dbk")
2643  {
2644  $doc = domxml_open_mem($a_xml);
2645 
2646  // get existing keywords
2647  $keywords = array();
2648 
2649  // find all Keyw tags
2650  $xpc = xpath_new_context($doc);
2651  $path = "//Keyw";
2652  $res = xpath_eval($xpc, $path);
2653  for ($i=0; $i < count($res->nodeset); $i++)
2654  {
2655  $k = trim(strip_tags($res->nodeset[$i]->get_content()));
2656  if (!in_array($k, $keywords))
2657  {
2658  $keywords[] = $k;
2659  }
2660  }
2661 
2662  $meta_type = ($this->getParentType() == "gdf")
2663  ? "gdf"
2664  : "pg";
2665  $meta_rep_id = $this->getParentId();
2666  $meta_id = $this->getId();
2667 
2668  include_once("./Services/MetaData/classes/class.ilMD.php");
2669  $md_obj = new ilMD($meta_rep_id, $meta_id, $meta_type);
2670  $mkeywords = array();
2671  $lang = "";
2672  if(is_object($md_section = $md_obj->getGeneral()))
2673  {
2674  foreach($ids = $md_section->getKeywordIds() as $id)
2675  {
2676  $md_key = $md_section->getKeyword($id);
2677  $mkeywords[] = strtolower($md_key->getKeyword());
2678  if ($lang == "")
2679  {
2680  $lang = $md_key->getKeywordLanguageCode();
2681  }
2682  }
2683  }
2684  if ($lang == "")
2685  {
2686  foreach($ids = $md_section->getLanguageIds() as $id)
2687  {
2688  $md_lang = $md_section->getLanguage($id);
2689  if ($lang == "")
2690  {
2691  $lang = $md_lang->getLanguageCode();
2692  }
2693  }
2694  }
2695  foreach ($keywords as $k)
2696  {
2697  if (!in_array(strtolower($k), $mkeywords))
2698  {
2699  if (trim($k) != "" && $lang != "")
2700  {
2701  $md_key = $md_section->addKeyword();
2702  $md_key->setKeyword(ilUtil::stripSlashes($k));
2703  $md_key->setKeywordLanguage(new ilMDLanguageItem($lang));
2704  $md_key->save();
2705  }
2706  $mkeywords[] = strtolower($k);
2707  }
2708  }
2709  }
2710  }
2711 
2717  function saveMobUsage($a_xml, $a_old_nr = 0)
2718  {
2719  $doc = domxml_open_mem($a_xml);
2720 
2721  // media aliases
2722  $xpc = xpath_new_context($doc);
2723  $path = "//MediaAlias";
2724  $res =& xpath_eval($xpc, $path);
2725  $usages = array();
2726  for ($i=0; $i < count($res->nodeset); $i++)
2727  {
2728  $id_arr = explode("_", $res->nodeset[$i]->get_attribute("OriginId"));
2729  $mob_id = $id_arr[count($id_arr) - 1];
2730  if ($mob_id > 0)
2731  {
2732  $usages[$mob_id] = true;
2733  }
2734  }
2735 
2736  // media objects
2737  $xpc = xpath_new_context($doc);
2738  $path = "//MediaObject/MetaData/General/Identifier";
2739  $res =& xpath_eval($xpc, $path);
2740  for ($i=0; $i < count($res->nodeset); $i++)
2741  {
2742  $mob_entry = $res->nodeset[$i]->get_attribute("Entry");
2743  $mob_arr = explode("_", $mob_entry);
2744  $mob_id = $mob_arr[count($mob_arr) - 1];
2745  if ($mob_id > 0)
2746  {
2747  $usages[$mob_id] = true;
2748  }
2749  }
2750 
2751  // internal links
2752  $xpc = xpath_new_context($doc);
2753  $path = "//IntLink[@Type='MediaObject']";
2754  $res =& xpath_eval($xpc, $path);
2755  for ($i=0; $i < count($res->nodeset); $i++)
2756  {
2757  $mob_target = $res->nodeset[$i]->get_attribute("Target");
2758  $mob_arr = explode("_", $mob_target);
2759  $mob_id = $mob_arr[count($mob_arr) - 1];
2760  if ($mob_id > 0)
2761  {
2762  $usages[$mob_id] = true;
2763  }
2764  }
2765 
2766  include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
2767  ilObjMediaObject::_deleteAllUsages($this->getParentType().":pg", $this->getId(), $a_old_nr);
2768  foreach($usages as $mob_id => $val)
2769  {
2770  ilObjMediaObject::_saveUsage($mob_id, $this->getParentType().":pg", $this->getId(), $a_old_nr);
2771  }
2772 
2773  return $usages;
2774  }
2775 
2779  function saveFileUsage($a_xml = "", $a_old_nr = 0)
2780  {
2781  $file_ids = $this->collectFileItems($a_xml, $a_old_nr);
2782  include_once("./Modules/File/classes/class.ilObjFile.php");
2783  ilObjFile::_deleteAllUsages($this->getParentType().":pg", $this->getId(), $a_old_nr);
2784  foreach($file_ids as $file_id)
2785  {
2786  ilObjFile::_saveUsage($file_id, $this->getParentType().":pg", $this->getId(), $a_old_nr);
2787  }
2788  }
2789 
2793  function saveContentIncludeUsage($a_xml = "", $a_old_nr = 0)
2794  {
2795  include_once("./Services/COPage/classes/class.ilPageContentUsage.php");
2796  $ci_ids = $this->collectContentIncludes($a_xml);
2797  ilPageContentUsage::deleteAllUsages("incl", $this->getParentType().":pg", $this->getId(), $a_old_nr);
2798  foreach($ci_ids as $ci_id)
2799  {
2800  if ((int) $ci_id["inst_id"] <= 0)
2801  {
2802  ilPageContentUsage::saveUsage("incl", $ci_id["id"], $this->getParentType().":pg", $this->getId(), $a_old_nr);
2803  }
2804  }
2805  }
2806 
2810  function collectContentIncludes($a_xml = "")
2811  {
2812  // determine all media aliases of the page
2813  if ($a_xml == "")
2814  {
2815  $this->buildDom();
2816  $xpc = xpath_new_context($this->dom);
2817  $path = "//ContentInclude";
2818  $res =& xpath_eval($xpc, $path);
2819  }
2820  else
2821  {
2822  $doc = domxml_open_mem($a_xml);
2823  $xpc = xpath_new_context($doc);
2824  $path = "//ContentInclude";
2825  $res =& xpath_eval($xpc, $path);
2826  }
2827  $ci_ids = array();
2828  for($i = 0; $i < count($res->nodeset); $i++)
2829  {
2830  $type = $res->nodeset[$i]->get_attribute("ContentType");
2831  $id = $res->nodeset[$i]->get_attribute("ContentId");
2832  $inst_id = $res->nodeset[$i]->get_attribute("InstId");
2833  $ci_ids[$type.":".$id.":".$inst_id] = array(
2834  "type" => $type, "id" => $id, "inst_id" => $inst_id);
2835  }
2836 
2837  return $ci_ids;
2838  }
2839 
2843  function saveSkillUsage($a_xml = "", $a_old_nr = 0)
2844  {
2845  include_once("./Services/COPage/classes/class.ilPageContentUsage.php");
2846  $skl_ids = $this->collectSkills($a_xml);
2847  ilPageContentUsage::deleteAllUsages("skmg", $this->getParentType().":pg", $this->getId(), $a_old_nr);
2848  foreach($skl_ids as $skl_id)
2849  {
2850  if ((int) $skl_id["inst_id"] <= 0)
2851  {
2852  ilPageContentUsage::saveUsage("skmg", $skl_id["id"], $this->getParentType().":pg", $this->getId(), $a_old_nr);
2853  }
2854  }
2855  }
2856 
2860  function collectSkills($a_xml = "")
2861  {
2862  // determine all media aliases of the page
2863  if ($a_xml == "")
2864  {
2865  $this->buildDom();
2866  $xpc = xpath_new_context($this->dom);
2867  $path = "//Skills";
2868  $res =& xpath_eval($xpc, $path);
2869  }
2870  else
2871  {
2872  $doc = domxml_open_mem($a_xml);
2873  $xpc = xpath_new_context($doc);
2874  $path = "//Skills";
2875  $res =& xpath_eval($xpc, $path);
2876  }
2877  $skl_ids = array();
2878  for($i = 0; $i < count($res->nodeset); $i++)
2879  {
2880  $user = $res->nodeset[$i]->get_attribute("User");
2881  $id = $res->nodeset[$i]->get_attribute("Id");
2882  $inst_id = $res->nodeset[$i]->get_attribute("InstId");
2883  $skl_ids[$user.":".$id.":".$inst_id] = array(
2884  "user" => $user, "id" => $id, "inst_id" => $inst_id);
2885  }
2886 
2887  return $skl_ids;
2888  }
2889 
2890 
2896  function saveStyleUsage($a_xml, $a_old_nr = 0)
2897  {
2898  global $ilDB;
2899 
2900  $doc = domxml_open_mem($a_xml);
2901 
2902  // media aliases
2903  $xpc = xpath_new_context($doc);
2904  $path = "//Paragraph | //Section | //MediaAlias | //FileItem".
2905  " | //Table | //TableData | //Tabs | //List";
2906  $res = xpath_eval($xpc, $path);
2907  $usages = array();
2908  for ($i=0; $i < count($res->nodeset); $i++)
2909  {
2910  switch ($res->nodeset[$i]->node_name())
2911  {
2912  case "Paragraph":
2913  $sname = $res->nodeset[$i]->get_attribute("Characteristic");
2914  $stype = "text_block";
2915  $template = 0;
2916  break;
2917 
2918  case "Section":
2919  $sname = $res->nodeset[$i]->get_attribute("Characteristic");
2920  $stype = "section";
2921  $template = 0;
2922  break;
2923 
2924  case "MediaAlias":
2925  $sname = $res->nodeset[$i]->get_attribute("Class");
2926  $stype = "media_cont";
2927  $template = 0;
2928  break;
2929 
2930  case "FileItem":
2931  $sname = $res->nodeset[$i]->get_attribute("Class");
2932  $stype = "flist_li";
2933  $template = 0;
2934  break;
2935 
2936  case "Table":
2937  $sname = $res->nodeset[$i]->get_attribute("Template");
2938  if ($sname == "")
2939  {
2940  $sname = $res->nodeset[$i]->get_attribute("Class");
2941  $stype = "table";
2942  $template = 0;
2943  }
2944  else
2945  {
2946  $stype = "table";
2947  $template = 1;
2948  }
2949  break;
2950 
2951  case "TableData":
2952  $sname = $res->nodeset[$i]->get_attribute("Class");
2953  $stype = "table_cell";
2954  $template = 0;
2955  break;
2956 
2957  case "Tabs":
2958  $sname = $res->nodeset[$i]->get_attribute("Template");
2959  if ($sname != "")
2960  {
2961  if ($res->nodeset[$i]->get_attribute("Type") == "HorizontalAccordion")
2962  {
2963  $stype = "haccordion";
2964  }
2965  if ($res->nodeset[$i]->get_attribute("Type") == "VerticalAccordion")
2966  {
2967  $stype = "vaccordion";
2968  }
2969  }
2970  $template = 1;
2971  break;
2972 
2973  case "List":
2974  $sname = $res->nodeset[$i]->get_attribute("Class");
2975  if ($res->nodeset[$i]->get_attribute("Type") == "Ordered")
2976  {
2977  $stype = "list_o";
2978  }
2979  else
2980  {
2981  $stype = "list_u";
2982  }
2983  $template = 0;
2984  break;
2985  }
2986  if ($sname != "" && $stype != "")
2987  {
2988  $usages[$sname.":".$stype.":".$template] = array("sname" => $sname,
2989  "stype" => $stype, "template" => $template);
2990  }
2991  }
2992 
2993  $ilDB->manipulate("DELETE FROM page_style_usage WHERE ".
2994  " page_id = ".$ilDB->quote($this->getId(), "integer").
2995  " AND page_type = ".$ilDB->quote($this->getParentType(), "text").
2996  " AND page_nr = ".$ilDB->quote($a_old_nr, "integer")
2997  );
2998 
2999  foreach ($usages as $u)
3000  {
3001  $ilDB->manipulate("INSERT INTO page_style_usage ".
3002  "(page_id, page_type, page_nr, template, stype, sname) VALUES (".
3003  $ilDB->quote($this->getId(), "integer").",".
3004  $ilDB->quote($this->getParentType(), "text").",".
3005  $ilDB->quote($a_old_nr, "integer").",".
3006  $ilDB->quote($u["template"], "integer").",".
3007  $ilDB->quote($u["stype"], "text").",".
3008  $ilDB->quote($u["sname"], "text").
3009  ")");
3010  }
3011  }
3012 
3018  {
3019  include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
3020  include_once("./Modules/File/classes/class.ilObjFile.php");
3022  $this->getId());
3024  $this->getId());
3025  $objs = array_merge($mobs, $files);
3026  return ilObject::_getLastUpdateOfObjects($objs);
3027  }
3028 
3034  function saveInternalLinks($a_xml)
3035  {
3036  global $ilDB;
3037 
3038 //echo "<br>PageObject::saveInternalLinks[".$this->getId()."]";
3039  $doc = domxml_open_mem($a_xml);
3040 
3041 
3042  include_once("./Services/COPage/classes/class.ilInternalLink.php");
3044 
3045  // get all internal links
3046  $xpc = xpath_new_context($doc);
3047  $path = "//IntLink";
3048  $res =& xpath_eval($xpc, $path);
3049  for ($i=0; $i < count($res->nodeset); $i++)
3050  {
3051  $link_type = $res->nodeset[$i]->get_attribute("Type");
3052 
3053  switch ($link_type)
3054  {
3055  case "StructureObject":
3056  $t_type = "st";
3057  break;
3058 
3059  case "PageObject":
3060  $t_type = "pg";
3061  break;
3062 
3063  case "GlossaryItem":
3064  $t_type = "git";
3065  break;
3066 
3067  case "MediaObject":
3068  $t_type = "mob";
3069  break;
3070 
3071  case "RepositoryItem":
3072  $t_type = "obj";
3073  break;
3074 
3075  case "File":
3076  $t_type = "file";
3077  break;
3078  }
3079 
3080  $target = $res->nodeset[$i]->get_attribute("Target");
3081  $target_arr = explode("_", $target);
3082  $t_id = $target_arr[count($target_arr) - 1];
3083 
3084  // link to other internal object
3085  if (is_int(strpos($target, "__")))
3086  {
3087  $t_inst = 0;
3088  }
3089  else // link to unresolved object in other installation
3090  {
3091  $t_inst = $target_arr[1];
3092  }
3093 
3094  if ($t_id > 0)
3095  {
3096  ilInternalLink::_saveLink($this->getParentType().":pg", $this->getId(), $t_type,
3097  $t_id, $t_inst);
3098  }
3099  }
3100 
3101  // *** STEP 2: Save question references of page ***
3102 
3103  // delete all reference records
3104  $ilDB->manipulateF("DELETE FROM page_question WHERE page_parent_type = %s ".
3105  " AND page_id = %s", array("text", "integer"),
3106  array($this->getParentType(), $this->getId()));
3107 
3108  // save question references of page
3109  $doc = domxml_open_mem($a_xml);
3110  $xpc = xpath_new_context($doc);
3111  $path = "//Question";
3112  $res = xpath_eval($xpc, $path);
3113  $q_ids = array();
3114  for ($i=0; $i < count($res->nodeset); $i++)
3115  {
3116  $q_ref = $res->nodeset[$i]->get_attribute("QRef");
3117 
3118  $inst_id = ilInternalLink::_extractInstOfTarget($q_ref);
3119  if (!($inst_id > 0))
3120  {
3121  $q_id = ilInternalLink::_extractObjIdOfTarget($q_ref);
3122  if ($q_id > 0)
3123  {
3124  $q_ids[$q_id] = $q_id;
3125  }
3126  }
3127  }
3128  foreach($q_ids as $qid)
3129  {
3130  $ilDB->manipulateF("INSERT INTO page_question (page_parent_type, page_id, question_id)".
3131  " VALUES (%s,%s,%s)",
3132  array("text", "integer", "integer"),
3133  array($this->getParentType(), $this->getId(), $qid));
3134  }
3135  }
3136 
3140  static function _getQuestionIdsForPage($a_parent_type, $a_page_id)
3141  {
3142  global $ilDB;
3143 
3144  $res = $ilDB->queryF("SELECT * FROM page_question WHERE page_parent_type = %s ".
3145  " AND page_id = %s",
3146  array("text", "integer"),
3147  array($a_parent_type, $a_page_id));
3148  $q_ids = array();
3149  while ($rec = $ilDB->fetchAssoc($res))
3150  {
3151  $q_ids[] = $rec["question_id"];
3152  }
3153 
3154  return $q_ids;
3155  }
3156 
3162  function saveAnchors($a_xml)
3163  {
3164  $doc = domxml_open_mem($a_xml);
3165 
3166  ilPageObject::_deleteAnchors($this->getParentType(), $this->getId());
3167 
3168  // get all anchors
3169  $xpc = xpath_new_context($doc);
3170  $path = "//Anchor";
3171  $res =& xpath_eval($xpc, $path);
3172  $saved = array();
3173  for ($i=0; $i < count($res->nodeset); $i++)
3174  {
3175  $name = $res->nodeset[$i]->get_attribute("Name");
3176  if (trim($name) != "" && !in_array($name, $saved))
3177  {
3178  ilPageObject::_saveAnchor($this->getParentType(), $this->getId(), $name);
3179  $saved[] = $name;
3180  }
3181  }
3182 
3183  }
3184 
3188  static function _deleteAnchors($a_parent_type, $a_page_id)
3189  {
3190  global $ilDB;
3191 
3192  $st = $ilDB->prepareManip("DELETE FROM page_anchor WHERE page_parent_type = ? ".
3193  " AND page_id = ?", array("text", "integer"));
3194  $ilDB->execute($st, array($a_parent_type, $a_page_id));
3195  }
3196 
3200  static function _saveAnchor($a_parent_type, $a_page_id, $a_anchor_name)
3201  {
3202  global $ilDB;
3203 
3204  $st = $ilDB->prepareManip("INSERT INTO page_anchor (page_parent_type, page_id, anchor_name) ".
3205  " VALUES (?,?,?) ", array("text", "integer", "text"));
3206  $ilDB->execute($st, array($a_parent_type, $a_page_id, $a_anchor_name));
3207  }
3208 
3212  static function _readAnchors($a_parent_type, $a_page_id)
3213  {
3214  global $ilDB;
3215 
3216  $st = $ilDB->prepare("SELECT * FROM page_anchor WHERE page_parent_type = ? ".
3217  " AND page_id = ?", array("text", "integer"));
3218  $set = $ilDB->execute($st, array($a_parent_type, $a_page_id));
3219  $anchors = array();
3220  while ($rec = $ilDB->fetchAssoc($set))
3221  {
3222  $anchors[] = $rec["anchor_name"];
3223  }
3224  return $anchors;
3225  }
3226 
3230  function create()
3231  {
3232  $this->createFromXML();
3233  }
3234 
3242  function deleteContent($a_hid, $a_update = true, $a_pcid = "")
3243  {
3244  $curr_node =& $this->getContentNode($a_hid, $a_pcid);
3245  $curr_node->unlink_node($curr_node);
3246  if ($a_update)
3247  {
3248  return $this->update();
3249  }
3250  }
3251 
3252 
3260  function deleteContents($a_hids, $a_update = true, $a_self_ass = false)
3261  {
3262  if (!is_array($a_hids))
3263  {
3264  return;
3265  }
3266  foreach($a_hids as $a_hid)
3267  {
3268  $a_hid = explode(":", $a_hid);
3269 //echo "-".$a_hid[0]."-".$a_hid[1]."-";
3270 
3271  // do not delete question nodes in assessment pages
3272  if (!$this->checkForTag("Question", $a_hid[0], $a_hid[1]) || $a_self_ass)
3273  {
3274  $curr_node =& $this->getContentNode($a_hid[0], $a_hid[1]);
3275  if (is_object($curr_node))
3276  {
3277  $parent_node = $curr_node->parent_node();
3278  if ($parent_node->node_name() != "TableRow")
3279  {
3280  $curr_node->unlink_node($curr_node);
3281  }
3282  }
3283  }
3284  }
3285  if ($a_update)
3286  {
3287  return $this->update();
3288  }
3289  }
3290 
3296  function cutContents($a_hids)
3297  {
3298  $this->copyContents($a_hids);
3299  return $this->deleteContents($a_hids);
3300  }
3301 
3307  function copyContents($a_hids)
3308  {
3309  global $ilUser;
3310 //var_dump($a_hids);
3311  if (!is_array($a_hids))
3312  {
3313  return;
3314  }
3315 
3316  $time = date("Y-m-d H:i:s", time());
3317 
3318  $hier_ids = array();
3319  $skip = array();
3320  foreach($a_hids as $a_hid)
3321  {
3322  if ($a_hid == "")
3323  {
3324  continue;
3325  }
3326  $a_hid = explode(":", $a_hid);
3327 
3328  // check, whether new hid is child of existing one or vice versa
3329  reset($hier_ids);
3330  foreach($hier_ids as $h)
3331  {
3332  if($h."_" == substr($a_hid[0], 0, strlen($h) + 1))
3333  {
3334  $skip[] = $a_hid[0];
3335  }
3336  if($a_hid[0]."_" == substr($h, 0, strlen($a_hid[0]) + 1))
3337  {
3338  $skip[] = $h;
3339  }
3340  }
3341  $pc_id[$a_hid[0]] = $a_hid[1];
3342  if ($a_hid[0] != "")
3343  {
3344  $hier_ids[$a_hid[0]] = $a_hid[0];
3345  }
3346  }
3347  foreach ($skip as $s)
3348  {
3349  unset($hier_ids[$s]);
3350  }
3351  include_once("./Services/COPage/classes/class.ilPageContent.php");
3352  $hier_ids = ilPageContent::sortHierIds($hier_ids);
3353  $nr = 1;
3354  foreach($hier_ids as $hid)
3355  {
3356  $curr_node = $this->getContentNode($hid, $pc_id[$hid]);
3357  if (is_object($curr_node))
3358  {
3359  if ($curr_node->node_name() == "PageContent")
3360  {
3361  $content = $this->dom->dump_node($curr_node);
3362  // remove pc and hier ids
3363  $content = eregi_replace("PCID=\"[a-z0-9]*\"","",$content);
3364  $content = eregi_replace("HierId=\"[a-z0-9_]*\"","",$content);
3365 
3366  $ilUser->addToPCClipboard($content, $time, $nr);
3367  $nr++;
3368  }
3369  }
3370  }
3371  include_once("./Modules/LearningModule/classes/class.ilEditClipboard.php");
3373  }
3374 
3378  function pasteContents($a_hier_id, $a_self_ass = false)
3379  {
3380  global $ilUser;
3381 
3382  $a_hid = explode(":", $a_hier_id);
3383  $content = $ilUser->getPCClipboardContent();
3384 
3385  // we insert from last to first, because we insert all at the
3386  // same hier_id
3387  for ($i = count($content) - 1; $i >= 0; $i--)
3388  {
3389 
3390  $c = $content[$i];
3391  $temp_dom = domxml_open_mem('<?xml version="1.0" encoding="UTF-8"?>'.$c,
3392  DOMXML_LOAD_PARSING, $error);
3393  if(empty($error))
3394  {
3395  $this->handleCopiedContent($temp_dom, $a_self_ass);
3396  $xpc = xpath_new_context($temp_dom);
3397  $path = "//PageContent";
3398  $res = xpath_eval($xpc, $path);
3399  if (count($res->nodeset) > 0)
3400  {
3401  $new_pc_node = $res->nodeset[0];
3402  $cloned_pc_node = $new_pc_node->clone_node (true);
3403  $cloned_pc_node->unlink_node ($cloned_pc_node);
3404  $this->insertContentNode ($cloned_pc_node, $a_hid[0],
3405  IL_INSERT_AFTER, $a_hid[1]);
3406  }
3407  }
3408  else
3409  {
3410 //var_dump($error);
3411  }
3412  }
3413  $e = $this->update();
3414 //var_dump($e);
3415  }
3416 
3420  function switchEnableMultiple($a_hids, $a_update = true, $a_self_ass = false)
3421  {
3422  if (!is_array($a_hids))
3423  {
3424  return;
3425  }
3426  $obj = & $this->content_obj;
3427 
3428  foreach($a_hids as $a_hid)
3429  {
3430  $a_hid = explode(":", $a_hid);
3431  $curr_node =& $this->getContentNode($a_hid[0], $a_hid[1]);
3432  if (is_object($curr_node))
3433  {
3434  if ($curr_node->node_name() == "PageContent")
3435  {
3436  $cont_obj =& $this->getContentObject($a_hid[0], $a_hid[1]);
3437  if ($cont_obj->isEnabled ())
3438  {
3439  // do not deactivate question nodes in assessment pages
3440  if (!$this->checkForTag("Question", $a_hid[0], $a_hid[1]) || $a_self_ass)
3441  {
3442  $cont_obj->disable();
3443  }
3444  }
3445  else
3446  {
3447  $cont_obj->enable();
3448  }
3449  }
3450  }
3451  }
3452 
3453  if ($a_update)
3454  {
3455  return $this->update();
3456  }
3457  }
3458 
3459 
3467  function deleteContentFromHierId($a_hid, $a_update = true)
3468  {
3469  $hier_ids = $this->getHierIds();
3470 
3471  // iterate all hierarchical ids
3472  foreach ($hier_ids as $hier_id)
3473  {
3474  // delete top level nodes only
3475  if (!is_int(strpos($hier_id, "_")))
3476  {
3477  if ($hier_id != "pg" && $hier_id >= $a_hid)
3478  {
3479  $curr_node =& $this->getContentNode($hier_id);
3480  $curr_node->unlink_node($curr_node);
3481  }
3482  }
3483  }
3484  if ($a_update)
3485  {
3486  return $this->update();
3487  }
3488  }
3489 
3497  function deleteContentBeforeHierId($a_hid, $a_update = true)
3498  {
3499  $hier_ids = $this->getHierIds();
3500 
3501  // iterate all hierarchical ids
3502  foreach ($hier_ids as $hier_id)
3503  {
3504  // delete top level nodes only
3505  if (!is_int(strpos($hier_id, "_")))
3506  {
3507  if ($hier_id != "pg" && $hier_id < $a_hid)
3508  {
3509  $curr_node =& $this->getContentNode($hier_id);
3510  $curr_node->unlink_node($curr_node);
3511  }
3512  }
3513  }
3514  if ($a_update)
3515  {
3516  return $this->update();
3517  }
3518  }
3519 
3520 
3528  function _moveContentAfterHierId(&$a_source_page, &$a_target_page, $a_hid)
3529  {
3530  $hier_ids = $a_source_page->getHierIds();
3531 
3532  $copy_ids = array();
3533 
3534  // iterate all hierarchical ids
3535  foreach ($hier_ids as $hier_id)
3536  {
3537  // move top level nodes only
3538  if (!is_int(strpos($hier_id, "_")))
3539  {
3540  if ($hier_id != "pg" && $hier_id >= $a_hid)
3541  {
3542  $copy_ids[] = $hier_id;
3543  }
3544  }
3545  }
3546  asort($copy_ids);
3547 
3548  $parent_node =& $a_target_page->getContentNode("pg");
3549  $target_dom =& $a_target_page->getDom();
3550  $parent_childs =& $parent_node->child_nodes();
3551  $cnt_parent_childs = count($parent_childs);
3552 //echo "-$cnt_parent_childs-";
3553  $first_child =& $parent_childs[0];
3554  foreach($copy_ids as $copy_id)
3555  {
3556  $source_node =& $a_source_page->getContentNode($copy_id);
3557 
3558  $new_node =& $source_node->clone_node(true);
3559  $new_node->unlink_node($new_node);
3560 
3561  $source_node->unlink_node($source_node);
3562 
3563  if($cnt_parent_childs == 0)
3564  {
3565  $new_node =& $parent_node->append_child($new_node);
3566  }
3567  else
3568  {
3569  //$target_dom->import_node($new_node);
3570  $new_node =& $first_child->insert_before($new_node, $first_child);
3571  }
3572  $parent_childs =& $parent_node->child_nodes();
3573 
3574  //$cnt_parent_childs++;
3575  }
3576 
3577  $a_target_page->update();
3578  $a_source_page->update();
3579 
3580  }
3581 
3585  function insertContent(&$a_cont_obj, $a_pos, $a_mode = IL_INSERT_AFTER, $a_pcid = "")
3586  {
3587 //echo "-".$a_pos."-".$a_pcid."-";
3588  // move mode into container elements is always INSERT_CHILD
3589  $curr_node = $this->getContentNode($a_pos, $a_pcid);
3590  $curr_name = $curr_node->node_name();
3591  if (($curr_name == "TableData") || ($curr_name == "PageObject") ||
3592  ($curr_name == "ListItem") || ($curr_name == "Section")
3593  || ($curr_name == "Tab") || ($curr_name == "ContentPopup"))
3594  {
3595  $a_mode = IL_INSERT_CHILD;
3596  }
3597 
3598  $hid = $curr_node->get_attribute("HierId");
3599  if ($hid != "")
3600  {
3601 //echo "-".$a_pos."-".$hid."-";
3602  $a_pos = $hid;
3603  }
3604 
3605  if($a_mode != IL_INSERT_CHILD) // determine parent hierarchical id
3606  { // of sibling at $a_pos
3607  $pos = explode("_", $a_pos);
3608  $target_pos = array_pop($pos);
3609  $parent_pos = implode($pos, "_");
3610  }
3611  else // if we should insert a child, $a_pos is alreade the hierarchical id
3612  { // of the parent node
3613  $parent_pos = $a_pos;
3614  }
3615 
3616  // get the parent node
3617  if($parent_pos != "")
3618  {
3619  $parent_node =& $this->getContentNode($parent_pos);
3620  }
3621  else
3622  {
3623  $parent_node =& $this->getNode();
3624  }
3625 
3626  // count the parent children
3627  $parent_childs =& $parent_node->child_nodes();
3628  $cnt_parent_childs = count($parent_childs);
3629 //echo "ZZ$a_mode";
3630  switch ($a_mode)
3631  {
3632  // insert new node after sibling at $a_pos
3633  case IL_INSERT_AFTER:
3634  $new_node =& $a_cont_obj->getNode();
3635  //$a_pos = ilPageContent::incEdId($a_pos);
3636  //$curr_node =& $this->getContentNode($a_pos);
3637 //echo "behind $a_pos:";
3638  if($succ_node =& $curr_node->next_sibling())
3639  {
3640  $new_node =& $succ_node->insert_before($new_node, $succ_node);
3641  }
3642  else
3643  {
3644 //echo "movin doin append_child";
3645  $new_node =& $parent_node->append_child($new_node);
3646  }
3647  $a_cont_obj->setNode($new_node);
3648  break;
3649 
3650  case IL_INSERT_BEFORE:
3651 //echo "INSERT_BEF";
3652  $new_node =& $a_cont_obj->getNode();
3653  $succ_node =& $this->getContentNode($a_pos);
3654  $new_node =& $succ_node->insert_before($new_node, $succ_node);
3655  $a_cont_obj->setNode($new_node);
3656  break;
3657 
3658  // insert new node as first child of parent $a_pos (= $a_parent)
3659  case IL_INSERT_CHILD:
3660 //echo "insert as child:parent_childs:$cnt_parent_childs:<br>";
3661  $new_node =& $a_cont_obj->getNode();
3662  if($cnt_parent_childs == 0)
3663  {
3664  $new_node =& $parent_node->append_child($new_node);
3665  }
3666  else
3667  {
3668  $new_node =& $parent_childs[0]->insert_before($new_node, $parent_childs[0]);
3669  }
3670  $a_cont_obj->setNode($new_node);
3671 //echo "PP";
3672  break;
3673  }
3674 
3675  //check for PlaceHolder to remove in EditMode-keep in Layout Mode
3676  if (!$this->getLayoutMode()) {
3677  $sub_nodes = $curr_node->child_nodes() ;
3678  foreach ( $sub_nodes as $sub_node ) {
3679  if ($sub_node->node_name() == "PlaceHolder") {
3680  $curr_node->unlink_node();
3681  }
3682  }
3683  }
3684  }
3685 
3689  function insertContentNode(&$a_cont_node, $a_pos, $a_mode = IL_INSERT_AFTER, $a_pcid = "")
3690  {
3691  // move mode into container elements is always INSERT_CHILD
3692  $curr_node = $this->getContentNode($a_pos, $a_pcid);
3693  $curr_name = $curr_node->node_name();
3694  if (($curr_name == "TableData") || ($curr_name == "PageObject") ||
3695  ($curr_name == "ListItem") || ($curr_name == "Section")
3696  || ($curr_name == "Tab") || ($curr_name == "ContentPopup"))
3697  {
3698  $a_mode = IL_INSERT_CHILD;
3699  }
3700 
3701  $hid = $curr_node->get_attribute("HierId");
3702  if ($hid != "")
3703  {
3704  $a_pos = $hid;
3705  }
3706 
3707  if($a_mode != IL_INSERT_CHILD) // determine parent hierarchical id
3708  { // of sibling at $a_pos
3709  $pos = explode("_", $a_pos);
3710  $target_pos = array_pop($pos);
3711  $parent_pos = implode($pos, "_");
3712  }
3713  else // if we should insert a child, $a_pos is alreade the hierarchical id
3714  { // of the parent node
3715  $parent_pos = $a_pos;
3716  }
3717 
3718  // get the parent node
3719  if($parent_pos != "")
3720  {
3721  $parent_node =& $this->getContentNode($parent_pos);
3722  }
3723  else
3724  {
3725  $parent_node =& $this->getNode();
3726  }
3727 
3728  // count the parent children
3729  $parent_childs =& $parent_node->child_nodes();
3730  $cnt_parent_childs = count($parent_childs);
3731 
3732  switch ($a_mode)
3733  {
3734  // insert new node after sibling at $a_pos
3735  case IL_INSERT_AFTER:
3736  //$new_node =& $a_cont_obj->getNode();
3737  if($succ_node = $curr_node->next_sibling())
3738  {
3739  $a_cont_node = $succ_node->insert_before($a_cont_node, $succ_node);
3740  }
3741  else
3742  {
3743  $a_cont_node = $parent_node->append_child($a_cont_node);
3744  }
3745  //$a_cont_obj->setNode($new_node);
3746  break;
3747 
3748  case IL_INSERT_BEFORE:
3749  //$new_node =& $a_cont_obj->getNode();
3750  $succ_node = $this->getContentNode($a_pos);
3751  $a_cont_node = $succ_node->insert_before($a_cont_node, $succ_node);
3752  //$a_cont_obj->setNode($new_node);
3753  break;
3754 
3755  // insert new node as first child of parent $a_pos (= $a_parent)
3756  case IL_INSERT_CHILD:
3757  //$new_node =& $a_cont_obj->getNode();
3758  if($cnt_parent_childs == 0)
3759  {
3760  $a_cont_node = $parent_node->append_child($a_cont_node);
3761  }
3762  else
3763  {
3764  $a_cont_node = $parent_childs[0]->insert_before($a_cont_node, $parent_childs[0]);
3765  }
3766  //$a_cont_obj->setNode($new_node);
3767  break;
3768  }
3769  }
3770 
3775  function moveContentBefore($a_source, $a_target, $a_spcid = "", $a_tpcid = "")
3776  {
3777  if($a_source == $a_target)
3778  {
3779  return;
3780  }
3781 
3782  // clone the node
3783  $content =& $this->getContentObject($a_source, $a_spcid);
3784  $source_node =& $content->getNode();
3785  $clone_node =& $source_node->clone_node(true);
3786 
3787  // delete source node
3788  $this->deleteContent($a_source, false, $a_spcid);
3789 
3790  // insert cloned node at target
3791  $content->setNode($clone_node);
3792  $this->insertContent($content, $a_target, IL_INSERT_BEFORE, $a_tpcid);
3793  return $this->update();
3794 
3795  }
3796 
3801  function moveContentAfter($a_source, $a_target, $a_spcid = "", $a_tpcid = "")
3802  {
3803  if($a_source == $a_target)
3804  {
3805  return;
3806  }
3807 
3808  // clone the node
3809  $content =& $this->getContentObject($a_source, $a_spcid);
3810  $source_node =& $content->getNode();
3811  $clone_node =& $source_node->clone_node(true);
3812 
3813  // delete source node
3814  $this->deleteContent($a_source, false, $a_spcid);
3815 
3816  // insert cloned node at target
3817  $content->setNode($clone_node);
3818  $this->insertContent($content, $a_target, IL_INSERT_AFTER, $a_tpcid);
3819  return $this->update();
3820  }
3821 
3825  function bbCode2XML(&$a_content)
3826  {
3827  $a_content = eregi_replace("\[com\]","<Comment>",$a_content);
3828  $a_content = eregi_replace("\[\/com\]","</Comment>",$a_content);
3829  $a_content = eregi_replace("\[emp]","<Emph>",$a_content);
3830  $a_content = eregi_replace("\[\/emp\]","</Emph>",$a_content);
3831  $a_content = eregi_replace("\[str]","<Strong>",$a_content);
3832  $a_content = eregi_replace("\[\/str\]","</Strong>",$a_content);
3833  }
3834 
3839  function insertInstIntoIDs($a_inst, $a_res_ref_to_obj_id = true)
3840  {
3841  // insert inst id into internal links
3842  $xpc = xpath_new_context($this->dom);
3843  $path = "//IntLink";
3844  $res =& xpath_eval($xpc, $path);
3845  for($i = 0; $i < count($res->nodeset); $i++)
3846  {
3847  $target = $res->nodeset[$i]->get_attribute("Target");
3848  $type = $res->nodeset[$i]->get_attribute("Type");
3849 
3850  if (substr($target, 0, 4) == "il__")
3851  {
3852  $id = substr($target, 4, strlen($target) - 4);
3853 
3854  // convert repository links obj_<ref_id> to <type>_<obj_id>
3855  if ($a_res_ref_to_obj_id && $type == "RepositoryItem")
3856  {
3857  $id_arr = explode("_", $id);
3858  $obj_id = ilObject::_lookupObjId($id_arr[1]);
3859  $otype = ilObject::_lookupType($obj_id);
3860  if ($obj_id > 0)
3861  {
3862  $id = $otype."_".$obj_id;
3863  }
3864  }
3865  $new_target = "il_".$a_inst."_".$id;
3866  $res->nodeset[$i]->set_attribute("Target", $new_target);
3867  }
3868  }
3869  unset($xpc);
3870 
3871  // insert inst id into media aliases
3872  $xpc = xpath_new_context($this->dom);
3873  $path = "//MediaAlias";
3874  $res =& xpath_eval($xpc, $path);
3875  for($i = 0; $i < count($res->nodeset); $i++)
3876  {
3877  $origin_id = $res->nodeset[$i]->get_attribute("OriginId");
3878  if (substr($origin_id, 0, 4) == "il__")
3879  {
3880  $new_id = "il_".$a_inst."_".substr($origin_id, 4, strlen($origin_id) - 4);
3881  $res->nodeset[$i]->set_attribute("OriginId", $new_id);
3882  }
3883  }
3884  unset($xpc);
3885 
3886  // insert inst id file item identifier entries
3887  $xpc = xpath_new_context($this->dom);
3888  $path = "//FileItem/Identifier";
3889  $res =& xpath_eval($xpc, $path);
3890  for($i = 0; $i < count($res->nodeset); $i++)
3891  {
3892  $origin_id = $res->nodeset[$i]->get_attribute("Entry");
3893  if (substr($origin_id, 0, 4) == "il__")
3894  {
3895  $new_id = "il_".$a_inst."_".substr($origin_id, 4, strlen($origin_id) - 4);
3896  $res->nodeset[$i]->set_attribute("Entry", $new_id);
3897  }
3898  }
3899  unset($xpc);
3900 
3901  // insert inst id into question references
3902  $xpc = xpath_new_context($this->dom);
3903  $path = "//Question";
3904  $res =& xpath_eval($xpc, $path);
3905  for($i = 0; $i < count($res->nodeset); $i++)
3906  {
3907  $qref = $res->nodeset[$i]->get_attribute("QRef");
3908 //echo "<br>setted:".$qref;
3909  if (substr($qref, 0, 4) == "il__")
3910  {
3911  $new_id = "il_".$a_inst."_".substr($qref, 4, strlen($qref) - 4);
3912 //echo "<br>setting:".$new_id;
3913  $res->nodeset[$i]->set_attribute("QRef", $new_id);
3914  }
3915  }
3916  unset($xpc);
3917 
3918  }
3919 
3924  function highlightText($a_text, $proglang, $autoindent)
3925  {
3926 
3927  if (!$this->hasHighlighter($proglang)) {
3928  $proglang="plain";
3929  }
3930 
3931  require_once("./Services/COPage/syntax_highlight/php/HFile/HFile_".$proglang.".php");
3932  $classname = "HFile_$proglang";
3933  $h_instance = new $classname();
3934  if ($autoindent == "n") {
3935  $h_instance ->notrim = 1;
3936  $h_instance ->indent = array ("");
3937  $h_instance ->unindent = array ("");
3938  }
3939 
3940  $highlighter = new Core($h_instance, new Output_css());
3941  $a_text = $highlighter->highlight_text(html_entity_decode($a_text));
3942 
3943  return $a_text;
3944  }
3945 
3946  function hasHighlighter ($hfile_ext) {
3947  return file_exists ("Services/COPage/syntax_highlight/php/HFile/HFile_".$hfile_ext.".php");
3948  }
3949 
3955  function insertSourceCodeParagraphs($a_output, $outputmode = "presentation")
3956  {
3957  $xpc = xpath_new_context($this->dom);
3958  $path = "//Paragraph"; //"[@Characteristic = 'Code']";
3959  $res = & xpath_eval($xpc, $path);
3960  for($i = 0; $i < count($res->nodeset); $i++)
3961  {
3962  $context_node = $res->nodeset[$i];
3963  $char = $context_node->get_attribute('Characteristic');
3964 
3965  if ($char != "Code")
3966  continue;
3967 
3968  $n = $context_node->parent_node();
3969  $char = $context_node->get_attribute('Characteristic');
3970  $subchar = $context_node->get_attribute('SubCharacteristic');
3971  $showlinenumbers = $context_node->get_attribute('ShowLineNumbers');
3972  $downloadtitle = $context_node->get_attribute('DownloadTitle');
3973  $autoindent = $context_node->get_attribute('AutoIndent');
3974 
3975  $content = "";
3976 
3977  // get XML Content
3978  $childs = $context_node->child_nodes();
3979 
3980  for($j=0; $j<count($childs); $j++)
3981  {
3982  $content .= $this->dom->dump_node($childs[$j]);
3983  }
3984 
3985  while ($context_node->has_child_nodes ())
3986  {
3987  $node_del = $context_node->first_child ();
3988  $context_node->remove_child ($node_del);
3989  }
3990 
3991  $content = str_replace("<br />", "<br/>", utf8_decode($content) );
3992  $content = str_replace("<br/>", "\n", $content);
3993  $rownums = count(split ("\n",$content));
3994 
3995  $plain_content = html_entity_decode($content);
3996  $plain_content = preg_replace ("/\&#x([1-9a-f]{2});?/ise","chr (base_convert (\\1, 16, 10))",$plain_content);
3997  $plain_content = preg_replace ("/\&#(\d+);?/ise","chr (\\1)",$plain_content);
3998  $content = utf8_encode($this->highlightText($plain_content, $subchar, $autoindent));
3999 
4000  $content = str_replace("&amp;lt;", "&lt;", $content);
4001  $content = str_replace("&amp;gt;", "&gt;", $content);
4002 // $content = str_replace("&", "&amp;", $content);
4003 //var_dump($content);
4004  $rows = "<tr valign=\"top\">";
4005  $rownumbers = "";
4006  $linenumbers= "";
4007 
4008  //if we have to show line numbers
4009  if (strcmp($showlinenumbers,"y")==0)
4010  {
4011  $linenumbers = "<td nowrap=\"nowrap\" class=\"ilc_LineNumbers\" >";
4012  $linenumbers .= "<pre class=\"ilc_Code\">";
4013 
4014  for ($j=0; $j < $rownums; $j++)
4015  {
4016  $indentno = strlen($rownums) - strlen($j+1) + 2;
4017  $rownumeration = ($j+1);
4018  $linenumbers .= "<span class=\"ilc_LineNumber\">$rownumeration</span>";
4019  if ($j < $rownums-1)
4020  {
4021  $linenumbers .= "\n";
4022  }
4023  }
4024  $linenumbers .= "</pre>";
4025  $linenumbers .= "</td>";
4026  }
4027 
4028  $rows .= $linenumbers."<td class=\"ilc_Sourcecode\"><pre class=\"ilc_Code\">".$content."</pre></td>";
4029  $rows .= "</tr>";
4030 
4031  // fix for ie explorer which is not able to produce empty line feeds with <br /><br />;
4032  // workaround: add a space after each br.
4033  $newcontent = str_replace("\n", "<br/>",$rows);
4034  // fix for IE
4035  $newcontent = str_replace("<br/><br/>", "<br/> <br/>",$newcontent);
4036  // falls drei hintereinander...
4037  $newcontent = str_replace("<br/><br/>", "<br/> <br/>",$newcontent);
4038 
4039  // workaround for preventing template engine
4040  // from hiding paragraph text that is enclosed
4041  // in curly brackets (e.g. "{a}", see ilLMEditorGUI::executeCommand())
4042  $newcontent = str_replace("{", "&#123;", $newcontent);
4043  $newcontent = str_replace("}", "&#125;", $newcontent);
4044 
4045 //echo htmlentities($newcontent);
4046  $a_output = str_replace("[[[[[Code;".($i + 1)."]]]]]", $newcontent, $a_output);
4047 
4048  if ($outputmode != "presentation" && is_object($this->offline_handler)
4049  && trim($downloadtitle) != "")
4050  {
4051  // call code handler for offline versions
4052  $this->offline_handler->handleCodeParagraph ($this->id, $i + 1, $downloadtitle, $plain_content);
4053  }
4054  }
4055 
4056  return $a_output;
4057  }
4058 
4059 
4063  function checkPCIds()
4064  {
4065  $this->builddom();
4066  $mydom = $this->dom;
4067 
4068  $sep = $path = "";
4069  foreach ($this->id_elements as $el)
4070  {
4071  $path.= $sep."//".$el."[not(@PCID)]";
4072  $sep = " | ";
4073  }
4074 
4075  $xpc = xpath_new_context($mydom);
4076  $res = & xpath_eval($xpc, $path);
4077 
4078  if (count ($res->nodeset) > 0)
4079  {
4080  return false;
4081  }
4082  return true;
4083  }
4084 
4091  function getAllPCIds()
4092  {
4093  $this->builddom();
4094  $mydom = $this->dom;
4095 
4096  $pcids = array();
4097 
4098  $sep = $path = "";
4099  foreach ($this->id_elements as $el)
4100  {
4101  $path.= $sep."//".$el."[@PCID]";
4102  $sep = " | ";
4103  }
4104 
4105  // get existing ids
4106  $xpc = xpath_new_context($mydom);
4107  $res = & xpath_eval($xpc, $path);
4108 
4109  for ($i = 0; $i < count ($res->nodeset); $i++)
4110  {
4111  $node = $res->nodeset[$i];
4112  $pcids[] = $node->get_attribute("PCID");
4113  }
4114  return $pcids;
4115  }
4116 
4123  function existsPCId($a_pc_id)
4124  {
4125  $this->builddom();
4126  $mydom = $this->dom;
4127 
4128  $pcids = array();
4129 
4130  $sep = $path = "";
4131  foreach ($this->id_elements as $el)
4132  {
4133  $path.= $sep."//".$el."[@PCID='".$a_pc_id."']";
4134  $sep = " | ";
4135  }
4136 
4137  // get existing ids
4138  $xpc = xpath_new_context($mydom);
4139  $res = & xpath_eval($xpc, $path);
4140  return (count($res->nodeset) > 0);
4141  }
4142 
4149  function generatePcId($a_pc_ids = false)
4150  {
4151  if ($a_pc_ids === false)
4152  {
4153  $a_pc_ids = $this->getAllPCIds();
4154  }
4155  $id = ilUtil::randomHash(10, $a_pc_ids);
4156  return $id;
4157  }
4158 
4159 
4163  function insertPCIds()
4164  {
4165  $this->builddom();
4166  $mydom = $this->dom;
4167 
4168  $pcids = $this->getAllPCIds();
4169 
4170  // add missing ones
4171  $sep = $path = "";
4172  foreach ($this->id_elements as $el)
4173  {
4174  $path.= $sep."//".$el."[not(@PCID)]";
4175  $sep = " | ";
4176  }
4177  $xpc = xpath_new_context($mydom);
4178  $res = & xpath_eval($xpc, $path);
4179 
4180  for ($i = 0; $i < count ($res->nodeset); $i++)
4181  {
4182  $node = $res->nodeset[$i];
4183  $id = ilUtil::randomHash(10, $pcids);
4184  $pcids[] = $id;
4185 //echo "setting-".$id."-";
4186  $res->nodeset[$i]->set_attribute("PCID", $id);
4187  }
4188  }
4189 
4194  {
4195  $this->builddom();
4196  $this->addHierIds();
4197  $mydom = $this->dom;
4198 
4199  // get existing ids
4200  $path = "//PageContent";
4201  $xpc = xpath_new_context($mydom);
4202  $res = & xpath_eval($xpc, $path);
4203 
4204  $hashes = array();
4205  require_once("./Services/COPage/classes/class.ilPCParagraph.php");
4206  for ($i = 0; $i < count ($res->nodeset); $i++)
4207  {
4208  $hier_id = $res->nodeset[$i]->get_attribute("HierId");
4209  $pc_id = $res->nodeset[$i]->get_attribute("PCID");
4210  $dump = $mydom->dump_node($res->nodeset[$i]);
4211  if (($hpos = strpos($dump, ' HierId="'.$hier_id.'"')) > 0)
4212  {
4213  $dump = substr($dump, 0, $hpos).
4214  substr($dump, $hpos + strlen(' HierId="'.$hier_id.'"'));
4215  }
4216 
4217  $childs = $res->nodeset[$i]->child_nodes();
4218  $content = "";
4219  if ($childs[0] && $childs[0]->node_name() == "Paragraph")
4220  {
4221  $content = $mydom->dump_node($childs[0]);
4222  $content = substr($content, strpos($content, ">") + 1,
4223  strrpos($content, "<") - (strpos($content, ">") + 1));
4224 //var_dump($content);
4225  $content = ilPCParagraph::xml2output($content);
4226 //var_dump($content);
4227  }
4228  //$hashes[$hier_id] =
4229  // array("PCID" => $pc_id, "hash" => md5($dump));
4230  $hashes[$pc_id] =
4231  array("hier_id" => $hier_id, "hash" => md5($dump), "content" => $content);
4232  }
4233 
4234  return $hashes;
4235  }
4236 
4240  function getQuestionIds()
4241  {
4242  $this->builddom();
4243  $mydom = $this->dom;
4244 
4245  // Get question IDs
4246  $path = "//Question";
4247  $xpc = xpath_new_context($mydom);
4248  $res = & xpath_eval($xpc, $path);
4249 
4250  $q_ids = array();
4251  include_once("./Services/COPage/classes/class.ilInternalLink.php");
4252  for ($i = 0; $i < count ($res->nodeset); $i++)
4253  {
4254  $qref = $res->nodeset[$i]->get_attribute("QRef");
4255 
4256  $inst_id = ilInternalLink::_extractInstOfTarget($qref);
4257  $obj_id = ilInternalLink::_extractObjIdOfTarget($qref);
4258 
4259  if (!($inst_id > 0))
4260  {
4261  if ($obj_id > 0)
4262  {
4263  $q_ids[] = $obj_id;
4264  }
4265  }
4266  }
4267  return $q_ids;
4268  }
4269 
4270  function send_paragraph ($par_id, $filename)
4271  {
4272  $this->builddom();
4273 
4274  $mydom = $this->dom;
4275 
4276  $xpc = xpath_new_context($mydom);
4277 
4278  //$path = "//PageContent[position () = $par_id]/Paragraph";
4279  //$path = "//Paragraph[$par_id]";
4280  $path = "/descendant::Paragraph[position() = $par_id]";
4281 
4282  $res = & xpath_eval($xpc, $path);
4283 
4284  if (count ($res->nodeset) != 1)
4285  die ("Should not happen");
4286 
4287  $context_node = $res->nodeset[0];
4288 
4289  // get plain text
4290 
4291  $childs = $context_node->child_nodes();
4292 
4293  for($j=0; $j<count($childs); $j++)
4294  {
4295  $content .= $mydom->dump_node($childs[$j]);
4296  }
4297 
4298  $content = str_replace("<br />", "\n", $content);
4299  $content = str_replace("<br/>", "\n", $content);
4300 
4301  $plain_content = html_entity_decode($content);
4302 
4303  ilUtil::deliverData($plain_content, $filename);
4304  /*
4305  $file_type = "application/octet-stream";
4306  header("Content-type: ".$file_type);
4307  header("Content-disposition: attachment; filename=\"$filename\"");
4308  echo $plain_content;*/
4309  exit();
4310  }
4311 
4315  function getFO()
4316  {
4317  $xml = $this->getXMLFromDom(false, true, true);
4318  $xsl = file_get_contents("./Services/COPage/xsl/page_fo.xsl");
4319  $args = array( '/_xml' => $xml, '/_xsl' => $xsl );
4320  $xh = xslt_create();
4321 
4322  $params = array ();
4323 
4324 
4325  $fo = xslt_process($xh,"arg:/_xml","arg:/_xsl",NULL,$args, $params);
4326  var_dump($fo);
4327  // do some replacements
4328  $fo = str_replace("\n", "", $fo);
4329  $fo = str_replace("<br/>", "<br>", $fo);
4330  $fo = str_replace("<br>", "\n", $fo);
4331 
4332  xslt_free($xh);
4333 
4334  //
4335  $fo = substr($fo, strpos($fo,">") + 1);
4336 //echo "<br><b>fo:</b><br>".htmlentities($fo); flush();
4337  return $fo;
4338  }
4339 
4340  function registerOfflineHandler ($handler) {
4341  $this->offline_handler = $handler;
4342  }
4343 
4347  function _lookupContainsDeactivatedElements($a_id, $a_parent_type)
4348  {
4349  global $ilDB;
4350 
4351  /*$query = "SELECT * FROM page_object WHERE page_id = ".
4352  $ilDB->quote($a_id)." AND ".
4353  " parent_type = ".$ilDB->quote($a_parent_type)." AND ".
4354  " content LIKE '% Enabled=\"False\"%'";*/
4355  $query = "SELECT * FROM page_object WHERE page_id = ".
4356  $ilDB->quote($a_id, "integer")." AND ".
4357  " parent_type = ".$ilDB->quote($a_parent_type, "text")." AND ".
4358  " inactive_elements = ".$ilDB->quote(1, "integer");
4359  $obj_set = $ilDB->query($query);
4360 
4361  if ($obj_rec = $obj_set->fetchRow(DB_FETCHMODE_ASSOC))
4362  {
4363  return true;
4364  }
4365 
4366  return false;
4367  }
4368 
4375  function containsDeactivatedElements($a_content)
4376  {
4377  if (strpos($a_content, " Enabled=\"False\""))
4378  {
4379  return true;
4380  }
4381  return false;
4382  }
4383 
4388  {
4389  global $ilDB;
4390 
4391  $h_query = "SELECT * FROM page_history ".
4392  " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
4393  " AND parent_type = ".$ilDB->quote($this->getParentType(), "text").
4394  " ORDER BY hdate DESC";
4395 
4396  $hset = $ilDB->query($h_query);
4397  $hentries = array();
4398 
4399  while ($hrec = $ilDB->fetchAssoc($hset))
4400  {
4401  $hrec["sortkey"] = (int) $hrec["nr"];
4402  $hrec["user"] = (int) $hrec["user_id"];
4403  $hentries[] = $hrec;
4404  }
4405 //var_dump($hentries);
4406  return $hentries;
4407  }
4408 
4412  function getHistoryEntry($a_old_nr)
4413  {
4414  global $ilDB;
4415 
4416  $res = $ilDB->queryF("SELECT * FROM page_history ".
4417  " WHERE page_id = %s ".
4418  " AND parent_type = %s ".
4419  " AND nr = %s",
4420  array("integer", "text", "integer"),
4421  array($this->getId(), $this->getParentType(), $a_old_nr));
4422  if ($hrec = $ilDB->fetchAssoc($res))
4423  {
4424  return $hrec;
4425  }
4426 
4427  return false;
4428  }
4429 
4430 
4437  function getHistoryInfo($a_nr)
4438  {
4439  global $ilDB;
4440 
4441  // determine previous entry
4442  $res = $ilDB->query("SELECT MAX(nr) mnr FROM page_history ".
4443  " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
4444  " AND parent_type = ".$ilDB->quote($this->getParentType(), "text").
4445  " AND nr < ".$ilDB->quote((int) $a_nr, "integer"));
4446  $row = $ilDB->fetchAssoc($res);
4447  if ($row["mnr"] > 0)
4448  {
4449  $res = $ilDB->query("SELECT * FROM page_history ".
4450  " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
4451  " AND parent_type = ".$ilDB->quote($this->getParentType(), "text").
4452  " AND nr = ".$ilDB->quote((int) $row["mnr"], "integer"));
4453  $row = $ilDB->fetchAssoc($res);
4454  $ret["previous"] = $row;
4455  }
4456 
4457  // determine next entry
4458  $res = $ilDB->query("SELECT MIN(nr) mnr FROM page_history ".
4459  " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
4460  " AND parent_type = ".$ilDB->quote($this->getParentType(), "text").
4461  " AND nr > ".$ilDB->quote((int) $a_nr, "integer"));
4462  $row = $ilDB->fetchAssoc($res);
4463  if ($row["mnr"] > 0)
4464  {
4465  $res = $ilDB->query("SELECT * FROM page_history ".
4466  " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
4467  " AND parent_type = ".$ilDB->quote($this->getParentType(), "text").
4468  " AND nr = ".$ilDB->quote((int) $row["mnr"], "integer"));
4469  $row = $ilDB->fetchAssoc($res);
4470  $ret["next"] = $row;
4471  }
4472 
4473  // current
4474  $res = $ilDB->query("SELECT * FROM page_history ".
4475  " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
4476  " AND parent_type = ".$ilDB->quote($this->getParentType(), "text").
4477  " AND nr = ".$ilDB->quote((int) $a_nr, "integer"));
4478  $row = $ilDB->fetchAssoc($res);
4479  $ret["current"] = $row;
4480 
4481  return $ret;
4482  }
4483 
4484  function addChangeDivClasses($a_hashes)
4485  {
4486  $xpc = xpath_new_context($this->dom);
4487  $path = "/*[1]";
4488  $res =& xpath_eval($xpc, $path);
4489  $rnode = $res->nodeset[0];
4490 
4491 //echo "A";
4492  foreach($a_hashes as $pc_id => $h)
4493  {
4494 //echo "B";
4495  if ($h["change"] != "")
4496  {
4497 //echo "<br>C-".$h["hier_id"]."-".$h["change"]."-";
4498  $dc_node = $this->dom->create_element("DivClass");
4499  $dc_node->set_attribute("HierId", $h["hier_id"]);
4500  $dc_node->set_attribute("Class", "ilEdit".$h["change"]);
4501  $dc_node = $rnode->append_child($dc_node);
4502  }
4503  }
4504  }
4505 
4512  function compareVersion($a_left, $a_right)
4513  {
4514  global $ilDB;
4515 
4516  // get page objects
4517  $l_page = new ilPageObject($this->getParentType(), $this->getId(), $a_left);
4518  $r_page = new ilPageObject($this->getParentType(), $this->getId(), $a_right);
4519 
4520  $l_hashes = $l_page->getPageContentsHashes();
4521  $r_hashes = $r_page->getPageContentsHashes();
4522 
4523  // determine all deleted and changed page elements
4524  foreach ($l_hashes as $pc_id => $h)
4525  {
4526  if (!isset($r_hashes[$pc_id]))
4527  {
4528  $l_hashes[$pc_id]["change"] = "Deleted";
4529  }
4530  else
4531  {
4532  if ($l_hashes[$pc_id]["hash"] != $r_hashes[$pc_id]["hash"])
4533  {
4534  $l_hashes[$pc_id]["change"] = "Modified";
4535  $r_hashes[$pc_id]["change"] = "Modified";
4536 
4537  include_once("./Services/COPage/mediawikidiff/class.WordLevelDiff.php");
4538  // if modified element is a paragraph, highlight changes
4539  if ($l_hashes[$pc_id]["content"] != "" &&
4540  $r_hashes[$pc_id]["content"] != "")
4541  {
4542  $new_left = str_replace("\n", "<br />", $l_hashes[$pc_id]["content"]);
4543  $new_right = str_replace("\n", "<br />", $r_hashes[$pc_id]["content"]);
4544  $wldiff = new WordLevelDiff(array($new_left),
4545  array($new_right));
4546  $new_left = $wldiff->orig();
4547  $new_right = $wldiff->closing();
4548  $l_page->setParagraphContent($l_hashes[$pc_id]["hier_id"], $new_left[0]);
4549  $r_page->setParagraphContent($l_hashes[$pc_id]["hier_id"], $new_right[0]);
4550  }
4551  }
4552  }
4553  }
4554 
4555  // determine all new paragraphs
4556  foreach ($r_hashes as $pc_id => $h)
4557  {
4558  if (!isset($l_hashes[$pc_id]))
4559  {
4560  $r_hashes[$pc_id]["change"] = "New";
4561  }
4562  }
4563 
4564  $l_page->addChangeDivClasses($l_hashes);
4565  $r_page->addChangeDivClasses($r_hashes);
4566 
4567  return array("l_page" => $l_page, "r_page" => $r_page,
4568  "l_changes" => $l_hashes, "r_changes" => $r_hashes);
4569  }
4570 
4574  function increaseViewCnt()
4575  {
4576  global $ilDB;
4577 
4578  $ilDB->manipulate("UPDATE page_object ".
4579  " SET view_cnt = view_cnt + 1 ".
4580  " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
4581  " AND parent_type = ".$ilDB->quote($this->getParentType(), "text"));
4582  //$ilDB->query($q);
4583  }
4584 
4592  static function getRecentChanges($a_parent_type, $a_parent_id, $a_period = 30)
4593  {
4594  global $ilDB;
4595 
4596  $page_changes = array();
4597  $limit_ts = date('Y-m-d H:i:s', time() - ($a_period * 24 * 60 * 60));
4598  $q = "SELECT * FROM page_object ".
4599  " WHERE parent_id = ".$ilDB->quote($a_parent_id, "integer").
4600  " AND parent_type = ".$ilDB->quote($a_parent_type, "text").
4601  " AND last_change >= ".$ilDB->quote($limit_ts, "timestamp");
4602  // " AND (TO_DAYS(now()) - TO_DAYS(last_change)) <= ".((int)$a_period);
4603  $set = $ilDB->query($q);
4604  while($page = $ilDB->fetchAssoc($set))
4605  {
4606  $page_changes[] = array("date" => $page["last_change"],
4607  "id" => $page["page_id"], "type" => "page",
4608  "user" => $page["last_change_user"]);
4609  }
4610 
4611  $and_str = "";
4612  if ($a_period > 0)
4613  {
4614  $limit_ts = date('Y-m-d H:i:s', time() - ($a_period * 24 * 60 * 60));
4615  $and_str = " AND hdate >= ".$ilDB->quote($limit_ts, "timestamp")." ";
4616  }
4617 
4618  $q = "SELECT * FROM page_history ".
4619  " WHERE parent_id = ".$ilDB->quote($a_parent_id, "integer").
4620  " AND parent_type = ".$ilDB->quote($a_parent_type, "text").
4621  $and_str;
4622  $set = $ilDB->query($q);
4623  while ($page = $ilDB->fetchAssoc($set))
4624  {
4625  $page_changes[] = array("date" => $page["hdate"],
4626  "id" => $page["page_id"], "type" => "hist", "nr" => $page["nr"],
4627  "user" => $page["user_id"]);
4628  }
4629 
4630  $page_changes = ilUtil::sortArray($page_changes, "date", "desc");
4631 
4632  return $page_changes;
4633  }
4634 
4642  static function getAllPages($a_parent_type, $a_parent_id)
4643  {
4644  global $ilDB;
4645 
4646  $page_changes = array();
4647 
4648  $q = "SELECT * FROM page_object ".
4649  " WHERE parent_id = ".$ilDB->quote($a_parent_id, "integer").
4650  " AND parent_type = ".$ilDB->quote($a_parent_type, "text");
4651  $set = $ilDB->query($q);
4652  $pages = array();
4653  while ($page = $ilDB->fetchAssoc($set))
4654  {
4655  $pages[$page["page_id"]] = array("date" => $page["last_change"],
4656  "id" => $page["page_id"], "user" => $page["last_change_user"]);
4657  }
4658 
4659  return $pages;
4660  }
4661 
4668  static function getNewPages($a_parent_type, $a_parent_id)
4669  {
4670  global $ilDB;
4671 
4672  $pages = array();
4673 
4674  $q = "SELECT * FROM page_object ".
4675  " WHERE parent_id = ".$ilDB->quote($a_parent_id, "integer").
4676  " AND parent_type = ".$ilDB->quote($a_parent_type, "text").
4677  " ORDER BY created DESC";
4678  $set = $ilDB->query($q);
4679  while($page = $ilDB->fetchAssoc($set))
4680  {
4681  if ($page["created"] != "")
4682  {
4683  $pages[] = array("created" => $page["created"],
4684  "id" => $page["page_id"],
4685  "user" => $page["create_user"],
4686  );
4687  }
4688  }
4689 
4690  return $pages;
4691  }
4692 
4699  static function getParentObjectContributors($a_parent_type, $a_parent_id)
4700  {
4701  global $ilDB;
4702 
4703  $contributors = array();
4704  $set = $ilDB->queryF("SELECT last_change_user FROM page_object ".
4705  " WHERE parent_id = %s AND parent_type = %s ".
4706  " AND last_change_user != %s",
4707  array("integer", "text", "integer"),
4708  array($a_parent_id, $a_parent_type, 0));
4709 
4710  while ($page = $ilDB->fetchAssoc($set))
4711  {
4712  $contributors[$page["last_change_user"]][$page["page_id"]] = 1;
4713  }
4714 
4715  $set = $ilDB->queryF("SELECT count(DISTINCT page_id, parent_type, hdate) as cnt, page_id, user_id FROM page_history ".
4716  " WHERE parent_id = %s AND parent_type = %s AND user_id != %s ".
4717  " GROUP BY page_id, user_id ",
4718  array("integer", "text", "integer"),
4719  array($a_parent_id, $a_parent_type, 0));
4720  while ($hpage = $ilDB->fetchAssoc($set))
4721  {
4722  $contributors[$hpage["user_id"]][$hpage["page_id"]] =
4723  $contributors[$hpage["user_id"]][$hpage["page_id"]] + $hpage["cnt"];
4724  }
4725 
4726  $c = array();
4727  foreach ($contributors as $k => $co)
4728  {
4729  if (ilObject::_lookupType($k) == "usr")
4730  {
4731  $name = ilObjUser::_lookupName($k);
4732  $c[] = array("user_id" => $k, "pages" => $co,
4733  "lastname" => $name["lastname"], "firstname" => $name["firstname"]);
4734  }
4735  }
4736 
4737  return $c;
4738  }
4739 
4746  static function getPageContributors($a_parent_type, $a_page_id)
4747  {
4748  global $ilDB;
4749 
4750  $contributors = array();
4751  $set = $ilDB->queryF("SELECT last_change_user FROM page_object ".
4752  " WHERE page_id = %s AND parent_type = %s ".
4753  " AND last_change_user != %s",
4754  array("integer", "text", "integer"),
4755  array($a_page_id, $a_parent_type, 0));
4756 
4757  while ($page = $ilDB->fetchAssoc($set))
4758  {
4759  $contributors[$page["last_change_user"]] = 1;
4760  }
4761 
4762  $set = $ilDB->queryF("SELECT count(*) as cnt, page_id, user_id FROM page_history ".
4763  " WHERE page_id = %s AND parent_type = %s AND user_id != %s ".
4764  " GROUP BY user_id, page_id ",
4765  array("integer", "text", "integer"),
4766  array($a_page_id, $a_parent_type, 0));
4767  while ($hpage = $ilDB->fetchAssoc($set))
4768  {
4769  $contributors[$hpage["user_id"]] =
4770  $contributors[$hpage["user_id"]] + $hpage["cnt"];
4771  }
4772 
4773  $c = array();
4774  foreach ($contributors as $k => $co)
4775  {
4776  $name = ilObjUser::_lookupName($k);
4777  $c[] = array("user_id" => $k, "pages" => $co,
4778  "lastname" => $name["lastname"], "firstname" => $name["firstname"]);
4779  }
4780 
4781  return $c;
4782  }
4783 
4787  function writeRenderedContent($a_content, $a_md5)
4788  {
4789  global $ilDB;
4790 
4791  $ilDB->update("page_object", array(
4792  "rendered_content" => array("clob", $a_content),
4793  "render_md5" => array("text", $a_md5),
4794  "rendered_time" => array("timestamp", ilUtil::now())
4795  ), array(
4796  "page_id" => array("integer", $this->getId()),
4797  "parent_type" => array("text", $this->getParentType())
4798  ));
4799  /*$st = $ilDB->prepareManip("UPDATE page_object ".
4800  " SET rendered_content = ?, render_md5 = ?, rendered_time = now()".
4801  " WHERE page_id = ? AND parent_type = ?",
4802  array("text", "text", "integer", "text"));
4803  $r = $ilDB->execute($st,
4804  array($a_content, $a_md5, $this->getId(), $this->getParentType()));*/
4805  }
4806 
4814  static function getPagesWithLinks($a_parent_type, $a_parent_id)
4815  {
4816  global $ilDB;
4817 
4818  $page_changes = array();
4819 
4820  $q = "SELECT * FROM page_object ".
4821  " WHERE parent_id = ".$ilDB->quote($a_parent_id, "integer").
4822  " AND parent_type = ".$ilDB->quote($a_parent_type, "text").
4823  " AND int_links = ".$ilDB->quote(1, "integer");
4824  $set = $ilDB->query($q);
4825  $pages = array();
4826  while ($page = $ilDB->fetchAssoc($set))
4827  {
4828  $pages[$page["page_id"]] = array("date" => $page["last_change"],
4829  "id" => $page["page_id"], "user" => $page["last_change_user"]);
4830  }
4831 
4832  return $pages;
4833  }
4834 
4841  function containsIntLinks($a_content)
4842  {
4843  if (strpos($a_content, "IntLink"))
4844  {
4845  return true;
4846  }
4847  return false;
4848  }
4849 
4854  {
4855  }
4856 }
4857 ?>