ILIAS  release_4-3 Revision
 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_3.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 
215  function setShowActivationInfo($a_val)
216  {
217  $this->show_page_act_info = $a_val;
218  }
219 
226  {
227  return $this->show_page_act_info;
228  }
229 
233  function read()
234  {
235  global $ilBench, $ilDB;
236 
237  $ilBench->start("ContentPresentation", "ilPageObject_read");
238 
239  $this->setActive(true);
240  if ($this->old_nr == 0)
241  {
242  $query = "SELECT * FROM page_object WHERE page_id = ".$ilDB->quote($this->id, "integer")." ".
243  "AND parent_type=".$ilDB->quote($this->getParentType(), "text");
244  $pg_set = $this->ilias->db->query($query);
245  $this->page_record = $ilDB->fetchAssoc($pg_set);
246  $this->setActive($this->page_record["active"]);
247  $this->setActivationStart($this->page_record["activation_start"]);
248  $this->setActivationEnd($this->page_record["activation_end"]);
249  $this->setShowActivationInfo($this->page_record["show_activation_info"]);
250  }
251  else
252  {
253  $query = "SELECT * FROM page_history WHERE ".
254  "page_id = ".$ilDB->quote($this->id, "integer")." ".
255  "AND parent_type=".$ilDB->quote($this->getParentType(), "text").
256  " AND nr = ".$ilDB->quote((int) $this->old_nr, "integer");
257  $pg_set = $ilDB->query($query);
258  $this->page_record = $ilDB->fetchAssoc($pg_set);
259  }
260  if (!$this->page_record)
261  {
262  if ($this->halt_on_error)
263  {
264  include_once("./Services/COPage/exceptions/class.ilCOPageNotFoundException.php");
265  throw new ilCOPageNotFoundException("Error: Page ".$this->id." is not in database".
266  " (parent type ".$this->getParentType().").");
267  //ilUtil::printBacktrace();
268  return;
269  }
270  else
271  {
272  $this->page_not_found = true;
273  return;
274  }
275  }
276  $this->xml = $this->page_record["content"];
277  $this->setParentId($this->page_record["parent_id"]);
278  $this->last_change_user = $this->page_record["last_change_user"];
279  $this->create_user = $this->page_record["create_user"];
280  $this->setRenderedContent($this->page_record["rendered_content"]);
281  $this->setRenderMd5($this->page_record["render_md5"]);
282  $this->setRenderedTime($this->page_record["rendered_time"]);
283  $this->setLastChange($this->page_record["last_change"]);
284 
285  $ilBench->stop("ContentPresentation", "ilPageObject_read");
286  }
287 
294  static function _exists($a_parent_type, $a_id)
295  {
296  global $ilDB;
297  if (isset(self::$exists[$a_parent_type.":".$a_id]))
298  {
299  return self::$exists[$a_parent_type.":".$a_id];
300  }
301 
302  $query = "SELECT page_id FROM page_object WHERE page_id = ".$ilDB->quote($a_id, "integer")." ".
303  "AND parent_type= ".$ilDB->quote($a_parent_type, "text");
304  $set = $ilDB->query($query);
305  if ($row = $ilDB->fetchAssoc($set))
306  {
307  self::$exists[$a_parent_type.":".$a_id] = true;
308  return true;
309  }
310  else
311  {
312  self::$exists[$a_parent_type.":".$a_id] = false;
313  return false;
314  }
315  }
316 
323  function _existsAndNotEmpty($a_parent_type, $a_id)
324  {
325  global $ilDB;
326 
327  $query = "SELECT page_id, is_empty FROM page_object WHERE page_id = ".$ilDB->quote($a_id, "integer")." ".
328  "AND parent_type= ".$ilDB->quote($a_parent_type, "text");
329 
330  $set = $ilDB->query($query);
331  if ($row = $ilDB->fetchAssoc($set))
332  {
333  if ($row["is_empty"] != 1)
334  {
335  return true;
336  }
337  }
338  return false;
339  }
340 
341  function buildDom($a_force = false)
342  {
343  global $ilBench;
344 
345  if ($this->dom_builded && !$a_force)
346  {
347  return;
348  }
349 
350 //echo "\n<br>buildDomWith:".$this->getId().":xml:".$this->getXMLContent(true).":<br>";
351 
352  $ilBench->start("ContentPresentation", "ilPageObject_buildDom");
353  $this->dom = @domxml_open_mem($this->getXMLContent(true), DOMXML_LOAD_VALIDATING, $error);
354  $ilBench->stop("ContentPresentation", "ilPageObject_buildDom");
355 
356  $xpc = xpath_new_context($this->dom);
357  $path = "//PageObject";
358  $res =& xpath_eval($xpc, $path);
359  if (count($res->nodeset) == 1)
360  {
361  $this->node =& $res->nodeset[0];
362  }
363 
364  if (empty($error))
365  {
366  $this->dom_builded = true;
367  return true;
368  }
369  else
370  {
371  return $error;
372  }
373  }
374 
375  function freeDom()
376  {
377  //$this->dom->free();
378  unset($this->dom);
379  }
380 
381  function &getDom()
382  {
383  return $this->dom;
384  }
385 
389  function setId($a_id)
390  {
391  $this->id = $a_id;
392  }
393 
394  function getId()
395  {
396  return $this->id;
397  }
398 
399  function setParentId($a_id)
400  {
401  $this->parent_id = $a_id;
402  }
403 
404  function getParentId()
405  {
406  return $this->parent_id;
407  }
408 
409  function setParentType($a_type)
410  {
411  $this->parent_type = $a_type;
412  }
413 
414  function getParentType()
415  {
416  return $this->parent_type;
417  }
418 
419  function addUpdateListener(&$a_object, $a_method, $a_parameters = "")
420  {
422  $this->update_listeners[$cnt]["object"] =& $a_object;
423  $this->update_listeners[$cnt]["method"] = $a_method;
424  $this->update_listeners[$cnt]["parameters"] = $a_parameters;
425  $this->update_listener_cnt++;
426  }
427 
429  {
430  for($i=0; $i<$this->update_listener_cnt; $i++)
431  {
432  $object =& $this->update_listeners[$i]["object"];
433  $method = $this->update_listeners[$i]["method"];
434  $parameters = $this->update_listeners[$i]["parameters"];
435  $object->$method($parameters);
436  }
437  }
438 
444  function setActive($a_active)
445  {
446  $this->active = $a_active;
447  }
448 
454  function getActive($a_check_scheduled_activation = false)
455  {
456  if ($a_check_scheduled_activation && !$this->active)
457  {
458  include_once("./Services/Calendar/classes/class.ilDateTime.php");
459  $start = new ilDateTime($this->getActivationStart(), IL_CAL_DATETIME);
460  $end = new ilDateTime($this->getActivationEnd(), IL_CAL_DATETIME);
461  $now = new ilDateTime(time(), IL_CAL_UNIX);
462  if (!ilDateTime::_before($now, $start) && !ilDateTime::_after($now, $end))
463  {
464  return true;
465  }
466  }
467  return $this->active;
468  }
469 
473  function _lookupActive($a_id, $a_parent_type, $a_check_scheduled_activation = false)
474  {
475  global $ilDB;
476 
477  $set = $ilDB->queryF("SELECT active, activation_start, activation_end FROM page_object WHERE page_id = %s".
478  " AND parent_type = %s",
479  array("integer", "text"),
480  array($a_id, $a_parent_type));
481  $rec = $ilDB->fetchAssoc($set);
482  $rec["n"] = ilUtil::now();
483 
484  if (!$rec["active"] && $a_check_scheduled_activation)
485  {
486  if ($rec["n"] >= $rec["activation_start"] &&
487  $rec["n"] <= $rec["activation_end"])
488  {
489  return true;
490  }
491  }
492 
493  return $rec["active"];
494  }
495 
499  static function _isScheduledActivation($a_id, $a_parent_type)
500  {
501  global $ilDB;
502 
503  $set = $ilDB->queryF("SELECT active, activation_start, activation_end FROM page_object WHERE page_id = %s".
504  " AND parent_type = %s", array("integer", "text"),
505  array($a_id, $a_parent_type));
506  $rec = $ilDB->fetchAssoc($set);
507 
508  if (!$rec["active"] && $rec["activation_start"] != "")
509  {
510  return true;
511  }
512 
513  return false;
514  }
515 
519  function _writeActive($a_id, $a_parent_type, $a_active, $a_reset_scheduled_activation = true)
520  {
521  global $ilDB;
522 
523  if ($a_reset_scheduled_activation)
524  {
525  $st = $ilDB->manipulateF("UPDATE page_object SET active = %s, activation_start = %s, ".
526  " activation_end = %s WHERE page_id = %s".
527  " AND parent_type = %s", array("boolean", "timestamp", "timestamp", "integer", "text"),
528  array($a_active, null, null, $a_id, $a_parent_type));
529  }
530  else
531  {
532  $st = $ilDB->prepareManip("UPDATE page_object SET active = %s WHERE page_id = %s".
533  " AND parent_type = %s", array("boolean", "integer", "text"),
534  array($a_active, $a_id, $a_parent_type));
535  }
536  }
537 
541  function _lookupActivationData($a_id, $a_parent_type)
542  {
543  global $ilDB;
544 
545  $set = $ilDB->queryF("SELECT active, activation_start, activation_end, show_activation_info FROM page_object WHERE page_id = %s".
546  " AND parent_type = %s",
547  array("integer", "text"),
548  array($a_id, $a_parent_type));
549  $rec = $ilDB->fetchAssoc($set);
550 
551  return $rec;
552  }
553 
554 
558  static function lookupParentId($a_id, $a_type)
559  {
560  global $ilDB;
561 
562  $res = $ilDB->query("SELECT parent_id FROM page_object WHERE page_id = ".$ilDB->quote($a_id, "integer")." ".
563  "AND parent_type=".$ilDB->quote($a_type, "text"));
564  $rec = $ilDB->fetchAssoc($res);
565  return $rec["parent_id"];
566  }
567 
571  function _writeParentId($a_parent_type, $a_pg_id, $a_par_id)
572  {
573  global $ilDB;
574 
575  $st = $ilDB->manipulateF("UPDATE page_object SET parent_id = %s WHERE page_id = %s".
576  " AND parent_type = %s", array("integer", "integer", "text"),
577  array($a_par_id, $a_pg_id, $a_parent_type));
578  }
579 
585  function setActivationStart($a_activationstart)
586  {
587  $this->activationstart = $a_activationstart;
588  }
589 
596  {
597  return $this->activationstart;
598  }
599 
605  function setActivationEnd($a_activationend)
606  {
607  $this->activationend = $a_activationend;
608  }
609 
615  function getActivationEnd()
616  {
617  return $this->activationend;
618  }
619 
628  function &getContentObject($a_hier_id, $a_pc_id = "")
629  {
630 //echo ":".$a_hier_id.":";
631 //echo "Content:".htmlentities($this->getXMLFromDOM()).":<br>";
632 //echo "ilPageObject::getContentObject:hierid:".$a_hier_id.":<br>";
633  $cont_node =& $this->getContentNode($a_hier_id, $a_pc_id);
634 //echo "ilPageObject::getContentObject:nodename:".$cont_node->node_name().":<br>";
635  if (!is_object($cont_node))
636  {
637  return false;
638  }
639  switch($cont_node->node_name())
640  {
641  case "PageContent":
642  $child_node =& $cont_node->first_child();
643 //echo "<br>nodename:".$child_node->node_name();
644  switch($child_node->node_name())
645  {
646  case "Paragraph":
647  require_once("./Services/COPage/classes/class.ilPCParagraph.php");
648  $par =& new ilPCParagraph($this->dom);
649  $par->setNode($cont_node);
650  $par->setHierId($a_hier_id);
651  $par->setPcId($a_pc_id);
652  return $par;
653 
654  case "Table":
655  if ($child_node->get_attribute("DataTable") == "y")
656  {
657  require_once("./Services/COPage/classes/class.ilPCDataTable.php");
658  $tab =& new ilPCDataTable($this->dom);
659  $tab->setNode($cont_node);
660  $tab->setHierId($a_hier_id);
661  }
662  else
663  {
664  require_once("./Services/COPage/classes/class.ilPCTable.php");
665  $tab =& new ilPCTable($this->dom);
666  $tab->setNode($cont_node);
667  $tab->setHierId($a_hier_id);
668  }
669  $tab->setPcId($a_pc_id);
670  return $tab;
671 
672  case "MediaObject":
673 if ($_GET["pgEdMediaMode"] != "") {echo "ilPageObject::error media"; exit;}
674 
675  //require_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
676  require_once("./Services/COPage/classes/class.ilPCMediaObject.php");
677 
678  $mal_node =& $child_node->first_child();
679 //echo "ilPageObject::getContentObject:nodename:".$mal_node->node_name().":<br>";
680  $id_arr = explode("_", $mal_node->get_attribute("OriginId"));
681  $mob_id = $id_arr[count($id_arr) - 1];
682 
683  // allow deletion of non-existing media objects
684  if (!ilObject::_exists($mob_id) && in_array("delete", $_POST))
685  {
686  $mob_id = 0;
687  }
688 
689  //$mob =& new ilObjMediaObject($mob_id);
690  $mob = new ilPCMediaObject($this->dom);
691  $mob->readMediaObject($mob_id);
692 
693  //$mob->setDom($this->dom);
694  $mob->setNode($cont_node);
695  $mob->setHierId($a_hier_id);
696  $mob->setPcId($a_pc_id);
697  return $mob;
698 
699  case "List":
700  require_once("./Services/COPage/classes/class.ilPCList.php");
701  $list = new ilPCList($this->dom);
702  $list->setNode($cont_node);
703  $list->setHierId($a_hier_id);
704  $list->setPcId($a_pc_id);
705  return $list;
706 
707  case "FileList":
708  require_once("./Services/COPage/classes/class.ilPCFileList.php");
709  $file_list = new ilPCFileList($this->dom);
710  $file_list->setNode($cont_node);
711  $file_list->setHierId($a_hier_id);
712  $file_list->setPcId($a_pc_id);
713  return $file_list;
714 
715  // note: assessment handling is forwarded to assessment gui classes
716  case "Question":
717  require_once("./Services/COPage/classes/class.ilPCQuestion.php");
718  $pc_question = new ilPCQuestion($this->dom);
719  $pc_question->setNode($cont_node);
720  $pc_question->setHierId($a_hier_id);
721  $pc_question->setPcId($a_pc_id);
722  return $pc_question;
723 
724  case "Section":
725  require_once("./Services/COPage/classes/class.ilPCSection.php");
726  $sec = new ilPCSection($this->dom);
727  $sec->setNode($cont_node);
728  $sec->setHierId($a_hier_id);
729  $sec->setPcId($a_pc_id);
730  return $sec;
731 
732  case "Resources":
733  require_once("./Services/COPage/classes/class.ilPCResources.php");
734  $res = new ilPCResources($this->dom);
735  $res->setNode($cont_node);
736  $res->setHierId($a_hier_id);
737  $res->setPcId($a_pc_id);
738  return $res;
739 
740  case 'LoginPageElement':
741  include_once './Services/COPage/classes/class.ilPCLoginPageElements.php';
742  $res = new ilPCLoginPageElements($this->dom);
743  $res->setNode($cont_node);
744  $res->setHierId($a_hier_id);
745  $res->setPcId($a_pcid);
746  return $res;
747 
748  case "Map":
749  require_once("./Services/COPage/classes/class.ilPCMap.php");
750  $map = new ilPCMap($this->dom);
751  $map->setNode($cont_node);
752  $map->setHierId($a_hier_id);
753  $map->setPcId($a_pc_id);
754  return $map;
755 
756  case "Tabs":
757  require_once("./Services/COPage/classes/class.ilPCTabs.php");
758  $map = new ilPCTabs($this->dom);
759  $map->setNode($cont_node);
760  $map->setHierId($a_hier_id);
761  $map->setPcId($a_pc_id);
762  return $map;
763 
764  case "Plugged":
765  require_once("./Services/COPage/classes/class.ilPCPlugged.php");
766  $plugged = new ilPCPlugged($this->dom);
767  $plugged->setNode($cont_node);
768  $plugged->setHierId($a_hier_id);
769  $plugged->setPcId($a_pc_id);
770  return $plugged;
771 
772  //Page-Layout-Support
773  case "PlaceHolder":
774  require_once("./Services/COPage/classes/class.ilPCPlaceHolder.php");
775  $placeholder = new ilPCPlaceHolder($this->dom);
776  $placeholder->setNode($cont_node);
777  $placeholder->setHierId($a_hier_id);
778  $placeholder->setPcId($a_pc_id);
779  return $placeholder;
780 
781  case "ContentInclude":
782  require_once("./Services/COPage/classes/class.ilPCContentInclude.php");
783  $inc =& new ilPCContentInclude($this->dom);
784  $inc->setNode($cont_node);
785  $inc->setHierId($a_hier_id);
786  $inc->setPcId($a_pc_id);
787  return $inc;
788 
789  case "InteractiveImage":
790  require_once("./Services/COPage/classes/class.ilPCInteractiveImage.php");
791  $iim = new ilPCInteractiveImage($this->dom);
792  $iim->setNode($cont_node);
793  $iim->setHierId($a_hier_id);
794  $iim->setPcId($a_pc_id);
795  return $iim;
796 
797  case "Profile":
798  require_once("./Services/COPage/classes/class.ilPCProfile.php");
799  $prof = new ilPCProfile($this->dom);
800  $prof->setNode($cont_node);
801  $prof->setHierId($a_hier_id);
802  $prof->setPcId($a_pc_id);
803  return $prof;
804 
805  case "Verification":
806  require_once("./Services/COPage/classes/class.ilPCVerification.php");
807  $vrfc = new ilPCVerification($this->dom);
808  $vrfc->setNode($cont_node);
809  $vrfc->setHierId($a_hier_id);
810  $vrfc->setPcId($a_pc_id);
811  return $vrfc;
812 
813  case "Blog":
814  require_once("./Services/COPage/classes/class.ilPCBlog.php");
815  $blog = new ilPCBlog($this->dom);
816  $blog->setNode($cont_node);
817  $blog->setHierId($a_hier_id);
818  $blog->setPcId($a_pc_id);
819  return $blog;
820 
821  case "QuestionOverview":
822  require_once("./Services/COPage/classes/class.ilPCQuestionOverview.php");
823  $qover = new ilPCQuestionOverview($this->dom);
824  $qover->setNode($cont_node);
825  $qover->setHierId($a_hier_id);
826  $qover->setPcId($a_pc_id);
827  return $qover;
828 
829  case "Skills":
830  require_once("./Services/COPage/classes/class.ilPCSkills.php");
831  $skill = new ilPCSkills($this->dom);
832  $skill->setNode($cont_node);
833  $skill->setHierId($a_hier_id);
834  $skill->setPcId($a_pc_id);
835  return $skill;
836  }
837  break;
838 
839  case "TableData":
840  require_once("./Services/COPage/classes/class.ilPCTableData.php");
841  $td =& new ilPCTableData($this->dom);
842  $td->setNode($cont_node);
843  $td->setHierId($a_hier_id);
844  return $td;
845 
846  case "ListItem":
847  require_once("./Services/COPage/classes/class.ilPCListItem.php");
848  $td =& new ilPCListItem($this->dom);
849  $td->setNode($cont_node);
850  $td->setHierId($a_hier_id);
851  return $td;
852 
853  case "FileItem":
854  require_once("./Services/COPage/classes/class.ilPCFileItem.php");
855  $file_item =& new ilPCFileItem($this->dom);
856  $file_item->setNode($cont_node);
857  $file_item->setHierId($a_hier_id);
858  return $file_item;
859 
860 /* case "Tab":
861  require_once("./Services/COPage/classes/class.ilPCTab.php");
862  $tab =& new ilPCTab($this->dom);
863  $tab->setNode($cont_node);
864  $tab->setHierId($a_hier_id);
865  return $tab;*/
866 
867  }
868  }
869 
876  function &getContentNode($a_hier_id, $a_pc_id = "")
877  {
878  $xpc = xpath_new_context($this->dom);
879  if($a_hier_id == "pg")
880  {
881  return $this->node;
882  }
883  else
884  {
885  // get per pc id
886  if ($a_pc_id != "")
887  {
888  $path = "//*[@PCID = '$a_pc_id']";
889  $res =& xpath_eval($xpc, $path);
890  if (count($res->nodeset) == 1)
891  {
892  $cont_node =& $res->nodeset[0];
893  return $cont_node;
894  }
895  }
896 
897  // fall back to hier id
898  $path = "//*[@HierId = '$a_hier_id']";
899  $res =& xpath_eval($xpc, $path);
900  if (count($res->nodeset) == 1)
901  {
902  $cont_node =& $res->nodeset[0];
903  return $cont_node;
904  }
905  }
906  }
907 
914  function checkForTag($a_content_tag, $a_hier_id, $a_pc_id = "")
915  {
916  $xpc = xpath_new_context($this->dom);
917  // get per pc id
918  if ($a_pc_id != "")
919  {
920  $path = "//*[@PCID = '$a_pc_id']//".$a_content_tag;
921  $res = xpath_eval($xpc, $path);
922  if (count($res->nodeset) > 0)
923  {
924  return true;
925  }
926  }
927 
928  // fall back to hier id
929  $path = "//*[@HierId = '$a_hier_id']//".$a_content_tag;
930  $res =& xpath_eval($xpc, $path);
931  if (count($res->nodeset) > 0)
932  {
933  return true;
934  }
935  return false;
936  }
937 
938  // only for test purposes
939  function lookforhier($a_hier_id)
940  {
941  $xpc = xpath_new_context($this->dom);
942  $path = "//*[@HierId = '$a_hier_id']";
943  $res =& xpath_eval($xpc, $path);
944  if (count($res->nodeset) == 1)
945  return "YES";
946  else
947  return "NO";
948  }
949 
950 
951  function &getNode()
952  {
953  return $this->node;
954  }
955 
956 
965  function setXMLContent($a_xml, $a_encoding = "UTF-8")
966  {
967  $this->encoding = $a_encoding;
968  $this->xml = $a_xml;
969  }
970 
977  function appendXMLContent($a_xml)
978  {
979  $this->xml.= $a_xml;
980  }
981 
982 
986  function getXMLContent($a_incl_head = false)
987  {
988  // build full http path for XML DOCTYPE header.
989  // Under windows a relative path doesn't work :-(
990  if($a_incl_head)
991  {
992 //echo "+".$this->encoding."+";
993  $enc_str = (!empty($this->encoding))
994  ? "encoding=\"".$this->encoding."\""
995  : "";
996  return "<?xml version=\"1.0\" $enc_str ?>".
997  "<!DOCTYPE PageObject SYSTEM \"".ILIAS_ABSOLUTE_PATH."/xml/".$this->cur_dtd."\">".
998  $this->xml;
999  }
1000  else
1001  {
1002  return $this->xml;
1003  }
1004  }
1005 
1010  function copyXmlContent($a_clone_mobs = false)
1011  {
1012  $xml = $this->getXmlContent();
1013  $temp_dom = domxml_open_mem('<?xml version="1.0" encoding="UTF-8"?>'.$xml,
1014  DOMXML_LOAD_PARSING, $error);
1015 
1016  if(empty($error))
1017  {
1018  $this->handleCopiedContent($temp_dom, true, $a_clone_mobs);
1019  }
1020  $xml = $temp_dom->dump_mem(0, $this->encoding);
1021  $xml = eregi_replace("<\?xml[^>]*>","",$xml);
1022  $xml = eregi_replace("<!DOCTYPE[^>]*>","",$xml);
1023 
1024  return $xml;
1025  }
1026 
1036  function handleCopiedContent($a_dom, $a_self_ass = true,
1037  $a_clone_mobs = false)
1038  {
1039  // handle question elements
1040  if ($a_self_ass)
1041  {
1042  $this->newQuestionCopies($a_dom);
1043  }
1044  else
1045  {
1046  $this->removeQuestions($a_dom);
1047  }
1048 
1049  // handle interactive images
1050  $this->newIIMCopies($a_dom);
1051 
1052  // handle media objects
1053  if ($a_clone_mobs)
1054  {
1055  $this->newMobCopies($a_dom);
1056  }
1057  }
1058 
1063  function newIIMCopies($temp_dom)
1064  {
1065  // Get question IDs
1066  $path = "//InteractiveImage/MediaAlias";
1067  $xpc = xpath_new_context($temp_dom);
1068  $res = & xpath_eval($xpc, $path);
1069 
1070  $q_ids = array();
1071  include_once("./Services/COPage/classes/class.ilInternalLink.php");
1072  for ($i = 0; $i < count ($res->nodeset); $i++)
1073  {
1074  $or_id = $res->nodeset[$i]->get_attribute("OriginId");
1075 
1076  $inst_id = ilInternalLink::_extractInstOfTarget($or_id);
1077  $mob_id = ilInternalLink::_extractObjIdOfTarget($or_id);
1078 
1079  if (!($inst_id > 0))
1080  {
1081  if ($mob_id > 0)
1082  {
1083  include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
1084  $media_object = new ilObjMediaObject($mob_id);
1085 
1086  // now copy this question and change reference to
1087  // new question id
1088  $new_mob = $media_object->duplicate();
1089 
1090  $res->nodeset[$i]->set_attribute("OriginId", "il__mob_".$new_mob->getId());
1091  }
1092  }
1093  }
1094  }
1095 
1099  function newMobCopies($temp_dom)
1100  {
1101  // Get question IDs
1102  $path = "//MediaObject/MediaAlias";
1103  $xpc = xpath_new_context($temp_dom);
1104  $res = & xpath_eval($xpc, $path);
1105 
1106  $q_ids = array();
1107  include_once("./Services/COPage/classes/class.ilInternalLink.php");
1108  for ($i = 0; $i < count ($res->nodeset); $i++)
1109  {
1110  $or_id = $res->nodeset[$i]->get_attribute("OriginId");
1111 
1112  $inst_id = ilInternalLink::_extractInstOfTarget($or_id);
1113  $mob_id = ilInternalLink::_extractObjIdOfTarget($or_id);
1114 
1115  if (!($inst_id > 0))
1116  {
1117  if ($mob_id > 0)
1118  {
1119  include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
1120  $media_object = new ilObjMediaObject($mob_id);
1121 
1122  // now copy this question and change reference to
1123  // new question id
1124  $new_mob = $media_object->duplicate();
1125 
1126  $res->nodeset[$i]->set_attribute("OriginId", "il__mob_".$new_mob->getId());
1127  }
1128  }
1129  }
1130  }
1131 
1136  function newQuestionCopies(&$temp_dom)
1137  {
1138  // Get question IDs
1139  $path = "//Question";
1140  $xpc = xpath_new_context($temp_dom);
1141  $res = & xpath_eval($xpc, $path);
1142 
1143  $q_ids = array();
1144  include_once("./Services/COPage/classes/class.ilInternalLink.php");
1145  for ($i = 0; $i < count ($res->nodeset); $i++)
1146  {
1147  $qref = $res->nodeset[$i]->get_attribute("QRef");
1148 
1149  $inst_id = ilInternalLink::_extractInstOfTarget($qref);
1151 
1152  if (!($inst_id > 0))
1153  {
1154  if ($q_id > 0)
1155  {
1156  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
1157  $question = assQuestion::_instanciateQuestion($q_id);
1158 
1159  // check if page for question exists
1160  // due to a bug in early 4.2.x version this is possible
1161  if (!ilPageObject::_exists("qpl", $q_id))
1162  {
1163  $question->createPageObject();
1164  }
1165 
1166  // now copy this question and change reference to
1167  // new question id
1168  $duplicate_id = $question->duplicate(false);
1169  $res->nodeset[$i]->set_attribute("QRef", "il__qst_".$duplicate_id);
1170  }
1171  }
1172  }
1173  }
1174 
1181  function removeQuestions(&$temp_dom)
1182  {
1183  // Get question IDs
1184  $path = "//Question";
1185  $xpc = xpath_new_context($temp_dom);
1186  $res = & xpath_eval($xpc, $path);
1187  for ($i = 0; $i < count ($res->nodeset); $i++)
1188  {
1189  $parent_node = $res->nodeset[$i]->parent_node();
1190  $parent_node->unlink_node($parent_node);
1191  }
1192  }
1193 
1201  {
1202  // Get question IDs
1203  $this->buildDom();
1204  $path = "//PageContent";
1205  $xpc = xpath_new_context($this->dom);
1206  $res = & xpath_eval($xpc, $path);
1207  return count ($res->nodeset);
1208  }
1209 
1214  function getXMLFromDom($a_incl_head = false, $a_append_mobs = false, $a_append_bib = false,
1215  $a_append_str = "", $a_omit_pageobject_tag = false)
1216  {
1217  if ($a_incl_head)
1218  {
1219 //echo "\n<br>#".$this->encoding."#";
1220  return $this->dom->dump_mem(0, $this->encoding);
1221  }
1222  else
1223  {
1224  // append multimedia object elements
1225  if ($a_append_mobs || $a_append_bib || $a_append_link_info)
1226  {
1227  $mobs = "";
1228  $bibs = "";
1229  if ($a_append_mobs)
1230  {
1231  $mobs =& $this->getMultimediaXML();
1232  }
1233  if ($a_append_bib)
1234  {
1235  $bibs =& $this->getBibliographyXML();
1236  }
1237  $trans =& $this->getLanguageVariablesXML();
1238  return "<dummy>".$this->dom->dump_node($this->node).$mobs.$bibs.$trans.$a_append_str."</dummy>";
1239  }
1240  else
1241  {
1242  if (is_object($this->dom))
1243  {
1244  if ($a_omit_pageobject_tag)
1245  {
1246  $xml = "";
1247  $childs =& $this->node->child_nodes();
1248  for($i = 0; $i < count($childs); $i++)
1249  {
1250  $xml.= $this->dom->dump_node($childs[$i]);
1251  }
1252  return $xml;
1253  }
1254  else
1255  {
1256  $xml = $this->dom->dump_mem(0, $this->encoding);
1257  $xml = eregi_replace("<\?xml[^>]*>","",$xml);
1258  $xml = eregi_replace("<!DOCTYPE[^>]*>","",$xml);
1259 
1260  return $xml;
1261 
1262  // don't use dump_node. This gives always entities.
1263  //return $this->dom->dump_node($this->node);
1264  }
1265  }
1266  else
1267  {
1268  return "";
1269  }
1270  }
1271  }
1272  }
1273 
1278  {
1279  global $lng;
1280 
1281  $xml = "<LVs>";
1282  $lang_vars = array("ed_insert_par", "ed_insert_code",
1283  "ed_insert_dtable", "ed_insert_atable", "ed_insert_media", "ed_insert_list",
1284  "ed_insert_filelist", "ed_paste_clip", "ed_edit", "ed_insert_section",
1285  "ed_edit_prop","ed_edit_files", "ed_edit_data", "ed_delete", "ed_moveafter", "ed_movebefore",
1286  "ed_go", "ed_new_row_after", "ed_new_row_before",
1287  "ed_new_col_after", "ed_new_col_before", "ed_delete_col",
1288  "ed_delete_row", "ed_class", "ed_width", "ed_align_left",
1289  "ed_align_right", "ed_align_center", "ed_align_left_float",
1290  "ed_align_right_float", "ed_delete_item", "ed_new_item_before",
1291  "ed_new_item_after", "ed_copy_clip", "please_select", "ed_split_page",
1292  "ed_item_up", "ed_item_down", "ed_row_up", "ed_row_down",
1293  "ed_col_left", "ed_col_right", "ed_split_page_next","ed_enable",
1294  "de_activate", "ed_insert_repobj", "ed_insert_login_page_element", "ed_insert_map", "ed_insert_tabs",
1295  "ed_insert_pcqst", "empty_question", "ed_paste","question_placeh","media_placeh","text_placeh",
1296  "ed_insert_plach","question_placehl","media_placehl","text_placehl",
1297  "pc_flist", "pc_par", "pc_mob", "pc_qst", "pc_sec", "pc_dtab", "pc_tab",
1298  "pc_code", "pc_vacc", "pc_hacc", "pc_res", "pc_map", "pc_list", "ed_insert_incl", "pc_incl",
1299  "pc_iim", "ed_insert_iim", "pc_prof", "ed_insert_profile", "pc_vrfc",
1300  "ed_insert_verification", "pc_blog", "ed_insert_blog", "ed_edit_multiple", "pc_qover", "ed_insert_qover",
1301  "pc_skills", "ed_insert_skills", "ed_cut", "ed_copy");
1302 
1303  foreach ($lang_vars as $lang_var)
1304  {
1305  $this->appendLangVarXML($xml, $lang_var);
1306  }
1307 
1308  $xml.= "</LVs>";
1309 
1310  return $xml;
1311  }
1312 
1313  function appendLangVarXML(&$xml, $var)
1314  {
1315  global $lng;
1316 
1317  $xml.= "<LV name=\"$var\" value=\"".$lng->txt("cont_".$var)."\"/>";
1318  }
1319 
1321  {
1322  if($this->dom)
1323  {
1324  require_once("./Services/COPage/classes/class.ilPCParagraph.php");
1325  $xpc = xpath_new_context($this->dom);
1326  $path = "//Paragraph[1]";
1327  $res =& xpath_eval($xpc, $path);
1328  if (count($res->nodeset) > 0)
1329  {
1330  $cont_node =& $res->nodeset[0]->parent_node();
1331  $par =& new ilPCParagraph($this->dom);
1332  $par->setNode($cont_node);
1333  return $par->getText();
1334  }
1335  }
1336  return "";
1337  }
1338 
1345  function setParagraphContent($a_hier_id, $a_content)
1346  {
1347  $node = $this->getContentNode($a_hier_id);
1348  if (is_object($node))
1349  {
1350  $node->set_content($a_content);
1351  }
1352  }
1353 
1354 
1363  function setContainsIntLink($a_contains_link)
1364  {
1365  $this->contains_int_link = $a_contains_link;
1366  }
1367 
1372  function containsIntLink()
1373  {
1374  return $this->contains_int_link;
1375  }
1376 
1377  function needsImportParsing($a_parse = "")
1378  {
1379 
1380  if ($a_parse === true)
1381  {
1382  $this->needs_parsing = true;
1383  }
1384  if ($a_parse === false)
1385  {
1386  $this->needs_parsing = false;
1387  }
1388  return $this->needs_parsing;
1389  }
1390 
1396  public function setContainsQuestion($a_val)
1397  {
1398  $this->contains_question = $a_val;
1399  }
1400 
1406  public function getContainsQuestion()
1407  {
1408  return $this->contains_question;
1409  }
1410 
1416  {
1417  global $ilias, $ilDB;
1418 
1419  // todo: access to $_GET and $_POST variables is not
1420  // allowed in non GUI classes!
1421  //
1422  // access to db table object_reference is not allowed here!
1423  $r = $ilias->db->query("SELECT * FROM object_reference WHERE ref_id=".
1424  $ilDB->quote($_GET["ref_id"],'integer'));
1425  $row = $r->fetchRow(DB_FETCHMODE_ASSOC);
1426 
1427  include_once("./Services/Xml/classes/class.ilNestedSetXML.php");
1428  $nested = new ilNestedSetXML();
1429  $bibs_xml = $nested->export($row["obj_id"], "bib");
1430 
1431  return $bibs_xml;
1432  }
1433 
1434 
1439  function collectMediaObjects($a_inline_only = true)
1440  {
1441 //echo htmlentities($this->getXMLFromDom());
1442  // determine all media aliases of the page
1443  $xpc = xpath_new_context($this->dom);
1444  $path = "//MediaObject/MediaAlias";
1445  $res =& xpath_eval($xpc, $path);
1446  $mob_ids = array();
1447  for($i = 0; $i < count($res->nodeset); $i++)
1448  {
1449  $id_arr = explode("_", $res->nodeset[$i]->get_attribute("OriginId"));
1450  $mob_id = $id_arr[count($id_arr) - 1];
1451  $mob_ids[$mob_id] = $mob_id;
1452  }
1453 
1454  // determine all media aliases of interactive images
1455  $xpc = xpath_new_context($this->dom);
1456  $path = "//InteractiveImage/MediaAlias";
1457  $res =& xpath_eval($xpc, $path);
1458  for($i = 0; $i < count($res->nodeset); $i++)
1459  {
1460  $id_arr = explode("_", $res->nodeset[$i]->get_attribute("OriginId"));
1461  $mob_id = $id_arr[count($id_arr) - 1];
1462  $mob_ids[$mob_id] = $mob_id;
1463  }
1464 
1465  // determine all inline internal media links
1466  $xpc = xpath_new_context($this->dom);
1467  $path = "//IntLink[@Type = 'MediaObject']";
1468  $res =& xpath_eval($xpc, $path);
1469 
1470  for($i = 0; $i < count($res->nodeset); $i++)
1471  {
1472  if (($res->nodeset[$i]->get_attribute("TargetFrame") == "") ||
1473  (!$a_inline_only))
1474  {
1475  $target = $res->nodeset[$i]->get_attribute("Target");
1476  $id_arr = explode("_", $target);
1477  if (($id_arr[1] == IL_INST_ID) ||
1478  (substr($target, 0, 4) == "il__"))
1479  {
1480  $mob_id = $id_arr[count($id_arr) - 1];
1481  if (ilObject::_exists($mob_id))
1482  {
1483  $mob_ids[$mob_id] = $mob_id;
1484  }
1485  }
1486  }
1487  }
1488 
1489  return $mob_ids;
1490  }
1491 
1492 
1496  function getInternalLinks($a_cnt_multiple = false)
1497  {
1498  // get all internal links of the page
1499  $xpc = xpath_new_context($this->dom);
1500  $path = "//IntLink";
1501  $res =& xpath_eval($xpc, $path);
1502 
1503  $links = array();
1504  $cnt_multiple = 1;
1505  for($i = 0; $i < count($res->nodeset); $i++)
1506  {
1507  $add = "";
1508  if ($a_cnt_multiple)
1509  {
1510  $add = ":".$cnt_multiple;
1511  }
1512  $target = $res->nodeset[$i]->get_attribute("Target");
1513  $type = $res->nodeset[$i]->get_attribute("Type");
1514  $targetframe = $res->nodeset[$i]->get_attribute("TargetFrame");
1515  $anchor = $res->nodeset[$i]->get_attribute("Anchor");
1516  $links[$target.":".$type.":".$targetframe.":".$anchor.$add] =
1517  array("Target" => $target, "Type" => $type,
1518  "TargetFrame" => $targetframe, "Anchor" => $anchor);
1519 
1520  // get links (image map areas) for inline media objects
1521  if ($type == "MediaObject" && $targetframe == "")
1522  {
1523  if (substr($target, 0, 4) =="il__")
1524  {
1525  $id_arr = explode("_", $target);
1526  $id = $id_arr[count($id_arr) - 1];
1527 
1528  $med_links = ilMediaItem::_getMapAreasIntLinks($id);
1529  foreach($med_links as $key => $med_link)
1530  {
1531  $links[$key] = $med_link;
1532  }
1533  }
1534 
1535  }
1536 //echo "<br>-:".$target.":".$type.":".$targetframe.":-";
1537  $cnt_multiple++;
1538  }
1539  unset($xpc);
1540 
1541  // get all media aliases
1542  $xpc = xpath_new_context($this->dom);
1543  $path = "//MediaAlias";
1544  $res =& xpath_eval($xpc, $path);
1545 
1546  require_once("Services/MediaObjects/classes/class.ilMediaItem.php");
1547  for($i = 0; $i < count($res->nodeset); $i++)
1548  {
1549  $oid = $res->nodeset[$i]->get_attribute("OriginId");
1550  if (substr($oid, 0, 4) =="il__")
1551  {
1552  $id_arr = explode("_", $oid);
1553  $id = $id_arr[count($id_arr) - 1];
1554 
1555  $med_links = ilMediaItem::_getMapAreasIntLinks($id);
1556  foreach($med_links as $key => $med_link)
1557  {
1558  $links[$key] = $med_link;
1559  }
1560  }
1561  }
1562  unset($xpc);
1563 
1564  return $links;
1565  }
1566 
1570  function collectFileItems($a_xml = "")
1571  {
1572 //echo "<br>PageObject::collectFileItems[".$this->getId()."]";
1573  // determine all media aliases of the page
1574  if ($a_xml == "")
1575  {
1576  $xpc = xpath_new_context($this->dom);
1577  $doc = $this->dom;
1578  $path = "//FileItem/Identifier";
1579  $res =& xpath_eval($xpc, $path);
1580  }
1581  else
1582  {
1583  $doc = domxml_open_mem($a_xml);
1584  $xpc = xpath_new_context($doc);
1585  $path = "//FileItem/Identifier";
1586  $res =& xpath_eval($xpc, $path);
1587  }
1588  $file_ids = array();
1589  for($i = 0; $i < count($res->nodeset); $i++)
1590  {
1591  $id_arr = explode("_", $res->nodeset[$i]->get_attribute("Entry"));
1592  $file_id = $id_arr[count($id_arr) - 1];
1593  $file_ids[$file_id] = $file_id;
1594  }
1595 
1596  // file items in download links
1597  $xpc = xpath_new_context($doc);
1598  $path = "//IntLink[@Type='File']";
1599  $res =& xpath_eval($xpc, $path);
1600  for($i = 0; $i < count($res->nodeset); $i++)
1601  {
1602  $t = $res->nodeset[$i]->get_attribute("Target");
1603  if (substr($t, 0, 9) == "il__dfile")
1604  {
1605  $id_arr = explode("_", $t);
1606  $file_id = $id_arr[count($id_arr) - 1];
1607  $file_ids[$file_id] = $file_id;
1608  }
1609  }
1610 //var_dump($file_ids); exit;
1611  return $file_ids;
1612  }
1613 
1618  function getMultimediaXML()
1619  {
1620  $mob_ids = $this->collectMediaObjects();
1621 
1622  // get xml of corresponding media objects
1623  $mobs_xml = "";
1624  require_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
1625  foreach($mob_ids as $mob_id => $dummy)
1626  {
1627  if (ilObject::_lookupType($mob_id) == "mob")
1628  {
1629  $mob_obj =& new ilObjMediaObject($mob_id);
1630  $mobs_xml .= $mob_obj->getXML(IL_MODE_OUTPUT);
1631  }
1632  }
1633 //var_dump($mobs_xml);
1634  return $mobs_xml;
1635  }
1636 
1640  function getMediaAliasElement($a_mob_id, $a_nr = 1)
1641  {
1642  $xpc = xpath_new_context($this->dom);
1643  $path = "//MediaObject/MediaAlias[@OriginId='il__mob_$a_mob_id']";
1644  $res =& xpath_eval($xpc, $path);
1645  $mal_node =& $res->nodeset[$a_nr - 1];
1646  $mob_node =& $mal_node->parent_node();
1647 
1648  return $this->dom->dump_node($mob_node);
1649  }
1650 
1656  function validateDom()
1657  {
1658  $this->stripHierIDs();
1659 
1660  // possible fix for #14820
1661  libxml_disable_entity_loader(false);
1662 
1663  $this->dom->validate($error);
1664  return $error;
1665  }
1666 
1682  function addHierIDs()
1683  {
1684  $this->hier_ids = array();
1685  $this->first_row_ids = array();
1686  $this->first_col_ids = array();
1687  $this->list_item_ids = array();
1688  $this->file_item_ids = array();
1689 
1690  // set hierarchical ids for Paragraphs, Tables, TableRows and TableData elements
1691  $xpc = xpath_new_context($this->dom);
1692  //$path = "//Paragraph | //Table | //TableRow | //TableData";
1693 
1694  $sep = $path = "";
1695  foreach ($this->id_elements as $el)
1696  {
1697  $path.= $sep."//".$el;
1698  $sep = " | ";
1699  }
1700 
1701  $res =& xpath_eval($xpc, $path);
1702  for($i = 0; $i < count($res->nodeset); $i++)
1703  {
1704  $cnode = $res->nodeset[$i];
1705  $ctag = $cnode->node_name();
1706 
1707  // get hierarchical id of previous sibling
1708  $sib_hier_id = "";
1709  while($cnode =& $cnode->previous_sibling())
1710  {
1711  if (($cnode->node_type() == XML_ELEMENT_NODE)
1712  && $cnode->has_attribute("HierId"))
1713  {
1714  $sib_hier_id = $cnode->get_attribute("HierId");
1715  //$sib_hier_id = $id_attr->value();
1716  break;
1717  }
1718  }
1719 
1720  if ($sib_hier_id != "") // set id to sibling id "+ 1"
1721  {
1722  require_once("./Services/COPage/classes/class.ilPageContent.php");
1723  $node_hier_id = ilPageContent::incEdId($sib_hier_id);
1724  $res->nodeset[$i]->set_attribute("HierId", $node_hier_id);
1725  $this->hier_ids[] = $node_hier_id;
1726  if ($ctag == "TableData")
1727  {
1728  if (substr($par_hier_id,strlen($par_hier_id)-2) == "_1")
1729  {
1730  $this->first_row_ids[] = $node_hier_id;
1731  }
1732  }
1733  if ($ctag == "ListItem")
1734  {
1735  $this->list_item_ids[] = $node_hier_id;
1736  }
1737  if ($ctag == "FileItem")
1738  {
1739  $this->file_item_ids[] = $node_hier_id;
1740  }
1741  }
1742  else // no sibling -> node is first child
1743  {
1744  // get hierarchical id of next parent
1745  $cnode = $res->nodeset[$i];
1746  $par_hier_id = "";
1747  while($cnode =& $cnode->parent_node())
1748  {
1749  if (($cnode->node_type() == XML_ELEMENT_NODE)
1750  && $cnode->has_attribute("HierId"))
1751  {
1752  $par_hier_id = $cnode->get_attribute("HierId");
1753  //$par_hier_id = $id_attr->value();
1754  break;
1755  }
1756  }
1757 //echo "<br>par:".$par_hier_id." ($ctag)";
1758  if (($par_hier_id != "") && ($par_hier_id != "pg")) // set id to parent_id."_1"
1759  {
1760  $node_hier_id = $par_hier_id."_1";
1761  $res->nodeset[$i]->set_attribute("HierId", $node_hier_id);
1762  $this->hier_ids[] = $node_hier_id;
1763  if ($ctag == "TableData")
1764  {
1765  $this->first_col_ids[] = $node_hier_id;
1766  if (substr($par_hier_id,strlen($par_hier_id)-2) == "_1")
1767  {
1768  $this->first_row_ids[] = $node_hier_id;
1769  }
1770  }
1771  if ($ctag == "ListItem")
1772  {
1773  $this->list_item_ids[] = $node_hier_id;
1774  }
1775  if ($ctag == "FileItem")
1776  {
1777  $this->file_item_ids[] = $node_hier_id;
1778  }
1779 
1780  }
1781  else // no sibling, no parent -> first node
1782  {
1783  $node_hier_id = "1";
1784  $res->nodeset[$i]->set_attribute("HierId", $node_hier_id);
1785  $this->hier_ids[] = $node_hier_id;
1786  }
1787  }
1788  }
1789 
1790  // set special hierarchical id "pg" for pageobject
1791  $xpc = xpath_new_context($this->dom);
1792  $path = "//PageObject";
1793  $res =& xpath_eval($xpc, $path);
1794  for($i = 0; $i < count($res->nodeset); $i++) // should only be 1
1795  {
1796  $res->nodeset[$i]->set_attribute("HierId", "pg");
1797  $this->hier_ids[] = "pg";
1798  }
1799  unset($xpc);
1800  }
1801 
1805  function getHierIds()
1806  {
1807  return $this->hier_ids;
1808  }
1809 
1813  function getFirstRowIds()
1814  {
1815  return $this->first_row_ids;
1816  }
1817 
1822  {
1823  return $this->first_col_ids;
1824  }
1825 
1829  function getListItemIds()
1830  {
1831  return $this->list_item_ids;
1832  }
1833 
1837  function getFileItemIds()
1838  {
1839  return $this->file_item_ids;
1840  }
1841 
1845  function stripHierIDs()
1846  {
1847  if(is_object($this->dom))
1848  {
1849  $xpc = xpath_new_context($this->dom);
1850  $path = "//*[@HierId]";
1851  $res =& xpath_eval($xpc, $path);
1852  for($i = 0; $i < count($res->nodeset); $i++) // should only be 1
1853  {
1854  if ($res->nodeset[$i]->has_attribute("HierId"))
1855  {
1856  $res->nodeset[$i]->remove_attribute("HierId");
1857  }
1858  }
1859  unset($xpc);
1860  }
1861  }
1862 
1866  function getHierIdsForPCIds($a_pc_ids)
1867  {
1868  if (!is_array($a_pc_ids) || count($a_pc_ids) == 0)
1869  {
1870  return array();
1871  }
1872  $ret = array();
1873 
1874  if(is_object($this->dom))
1875  {
1876  $xpc = xpath_new_context($this->dom);
1877  $path = "//*[@PCID]";
1878  $res =& xpath_eval($xpc, $path);
1879  for($i = 0; $i < count($res->nodeset); $i++) // should only be 1
1880  {
1881  $pc_id = $res->nodeset[$i]->get_attribute("PCID");
1882  if (in_array($pc_id, $a_pc_ids))
1883  {
1884  $ret[$pc_id] = $res->nodeset[$i]->get_attribute("HierId");
1885  }
1886  }
1887  unset($xpc);
1888  }
1889 //var_dump($ret);
1890  return $ret;
1891  }
1892 
1896  function addFileSizes()
1897  {
1898  $xpc = xpath_new_context($this->dom);
1899  $path = "//FileItem";
1900  $res =& xpath_eval($xpc, $path);
1901  for($i = 0; $i < count($res->nodeset); $i++)
1902  {
1903  $cnode =& $res->nodeset[$i];
1904  $size_node =& $this->dom->create_element("Size");
1905  $size_node =& $cnode->append_child($size_node);
1906 
1907  $childs =& $cnode->child_nodes();
1908  $size = "";
1909  for($j = 0; $j < count($childs); $j++)
1910  {
1911  if ($childs[$j]->node_name() == "Identifier")
1912  {
1913  if ($childs[$j]->has_attribute("Entry"))
1914  {
1915  $entry = $childs[$j]->get_attribute("Entry");
1916  $entry_arr = explode("_", $entry);
1917  $id = $entry_arr[count($entry_arr) - 1];
1918  require_once("./Modules/File/classes/class.ilObjFile.php");
1920  }
1921  }
1922  }
1923  $size_node->set_content($size);
1924  }
1925 
1926  unset($xpc);
1927  }
1928 
1933  function resolveIntLinks()
1934  {
1935  // resolve normal internal links
1936  $xpc = xpath_new_context($this->dom);
1937  $path = "//IntLink";
1938  $res =& xpath_eval($xpc, $path);
1939  for($i = 0; $i < count($res->nodeset); $i++)
1940  {
1941  $target = $res->nodeset[$i]->get_attribute("Target");
1942  $type = $res->nodeset[$i]->get_attribute("Type");
1943 
1944  $new_target = ilInternalLink::_getIdForImportId($type, $target);
1945  if ($new_target !== false)
1946  {
1947  $res->nodeset[$i]->set_attribute("Target", $new_target);
1948  }
1949  else // check wether link target is same installation
1950  {
1951  if (ilInternalLink::_extractInstOfTarget($target) == IL_INST_ID &&
1952  IL_INST_ID > 0 && $type != "RepositoryItem")
1953  {
1954  $new_target = ilInternalLink::_removeInstFromTarget($target);
1955  if (ilInternalLink::_exists($type, $new_target))
1956  {
1957  $res->nodeset[$i]->set_attribute("Target", $new_target);
1958  }
1959  }
1960  }
1961 
1962  }
1963  unset($xpc);
1964 
1965  // resolve internal links in map areas
1966  $xpc = xpath_new_context($this->dom);
1967  $path = "//MediaAlias";
1968  $res =& xpath_eval($xpc, $path);
1969 //echo "<br><b>page::resolve</b><br>";
1970 //echo "Content:".htmlentities($this->getXMLFromDOM()).":<br>";
1971  for($i = 0; $i < count($res->nodeset); $i++)
1972  {
1973  $orig_id = $res->nodeset[$i]->get_attribute("OriginId");
1974  $id_arr = explode("_", $orig_id);
1975  $mob_id = $id_arr[count($id_arr) - 1];
1977  }
1978  }
1979 
1986  function resolveMediaAliases($a_mapping)
1987  {
1988  // resolve normal internal links
1989  $xpc = xpath_new_context($this->dom);
1990  $path = "//MediaAlias";
1991  $res =& xpath_eval($xpc, $path);
1992  $changed = false;
1993  for($i = 0; $i < count($res->nodeset); $i++)
1994  {
1995  $old_id = $res->nodeset[$i]->get_attribute("OriginId");
1996  $old_id = explode("_", $old_id);
1997  $old_id = $old_id[count($old_id) - 1];
1998  if ($a_mapping[$old_id] > 0)
1999  {
2000  $res->nodeset[$i]->set_attribute("OriginId", "il__mob_".$a_mapping[$old_id]);
2001  $changed = true;
2002  }
2003  }
2004  unset($xpc);
2005 
2006  return $changed;
2007  }
2008 
2015  function resolveIIMMediaAliases($a_mapping)
2016  {
2017  // resolve normal internal links
2018  $xpc = xpath_new_context($this->dom);
2019  $path = "//InteractiveImage/MediaAlias";
2020  $res =& xpath_eval($xpc, $path);
2021  $changed = false;
2022  for($i = 0; $i < count($res->nodeset); $i++)
2023  {
2024  $old_id = $res->nodeset[$i]->get_attribute("OriginId");
2025  if ($a_mapping[$old_id] > 0)
2026  {
2027  $res->nodeset[$i]->set_attribute("OriginId", "il__mob_".$a_mapping[$old_id]);
2028  $changed = true;
2029  }
2030  }
2031  unset($xpc);
2032 
2033  return $changed;
2034  }
2035 
2042  function resolveFileItems($a_mapping)
2043  {
2044  // resolve normal internal links
2045  $xpc = xpath_new_context($this->dom);
2046  $path = "//FileItem/Identifier";
2047  $res =& xpath_eval($xpc, $path);
2048  $changed = false;
2049  for($i = 0; $i < count($res->nodeset); $i++)
2050  {
2051  $old_id = $res->nodeset[$i]->get_attribute("Entry");
2052  $old_id = explode("_", $old_id);
2053  $old_id = $old_id[count($old_id) - 1];
2054  if ($a_mapping[$old_id] > 0)
2055  {
2056  $res->nodeset[$i]->set_attribute("Entry", "il__file_".$a_mapping[$old_id]);
2057  $changed = true;
2058  }
2059  }
2060  unset($xpc);
2061 
2062  return $changed;
2063  }
2064 
2069  function resolveQuestionReferences($a_mapping)
2070  {
2071  // resolve normal internal links
2072  $xpc = xpath_new_context($this->dom);
2073  $path = "//Question";
2074  $res =& xpath_eval($xpc, $path);
2075  for($i = 0; $i < count($res->nodeset); $i++)
2076  {
2077  $qref = $res->nodeset[$i]->get_attribute("QRef");
2078 
2079  if (isset($a_mapping[$qref]))
2080  {
2081  $res->nodeset[$i]->set_attribute("QRef", "il__qst_".$a_mapping[$qref]["pool"]);
2082  }
2083  }
2084  unset($xpc);
2085  }
2086 
2087 
2094  function moveIntLinks($a_from_to)
2095  {
2096  $this->buildDom();
2097 
2098  $changed = false;
2099 
2100  // resolve normal internal links
2101  $xpc = xpath_new_context($this->dom);
2102  $path = "//IntLink";
2103  $res =& xpath_eval($xpc, $path);
2104  for($i = 0; $i < count($res->nodeset); $i++)
2105  {
2106  $target = $res->nodeset[$i]->get_attribute("Target");
2107  $type = $res->nodeset[$i]->get_attribute("Type");
2108  $obj_id = ilInternalLink::_extractObjIdOfTarget($target);
2109  if ($a_from_to[$obj_id] > 0 && is_int(strpos($target, "__")))
2110  {
2111  if ($type == "PageObject" && ilLMObject::_lookupType($a_from_to[$obj_id]) == "pg")
2112  {
2113  $res->nodeset[$i]->set_attribute("Target", "il__pg_".$a_from_to[$obj_id]);
2114  $changed = true;
2115  }
2116  if ($type == "StructureObject" && ilLMObject::_lookupType($a_from_to[$obj_id]) == "st")
2117  {
2118  $res->nodeset[$i]->set_attribute("Target", "il__st_".$a_from_to[$obj_id]);
2119  $changed = true;
2120  }
2121  }
2122  }
2123  unset($xpc);
2124 
2125  // map areas
2126  $this->addHierIDs();
2127  $xpc = xpath_new_context($this->dom);
2128  $path = "//MediaAlias";
2129  $res =& xpath_eval($xpc, $path);
2130 
2131  require_once("Services/MediaObjects/classes/class.ilMediaItem.php");
2132  require_once("Services/COPage/classes/class.ilMediaAliasItem.php");
2133 
2134  for($i = 0; $i < count($res->nodeset); $i++)
2135  {
2136  $media_object_node = $res->nodeset[$i]->parent_node();
2137  $page_content_node = $media_object_node->parent_node();
2138  $c_hier_id = $page_content_node->get_attribute("HierId");
2139 
2140  // first check, wheter we got instance map areas -> take these
2141  $std_alias_item = new ilMediaAliasItem($this->dom,
2142  $c_hier_id, "Standard");
2143  $areas = $std_alias_item->getMapAreas();
2144  $correction_needed = false;
2145  if (count($areas) > 0)
2146  {
2147  // check if correction needed
2148  foreach($areas as $area)
2149  {
2150  if ($area["Type"] == "PageObject" ||
2151  $area["Type"] == "StructureObject")
2152  {
2153  $t = $area["Target"];
2154  $tid = _extractObjIdOfTarget($t);
2155  if ($a_from_to[$tid] > 0)
2156  {
2157  $correction_needed = true;
2158  }
2159  }
2160  }
2161  }
2162  else
2163  {
2164  $areas = array();
2165 
2166  // get object map areas and check whether at least one must
2167  // be corrected
2168  $oid = $res->nodeset[$i]->get_attribute("OriginId");
2169  if (substr($oid, 0, 4) =="il__")
2170  {
2171  $id_arr = explode("_", $oid);
2172  $id = $id_arr[count($id_arr) - 1];
2173 
2174  $mob = new ilObjMediaObject($id);
2175  $med_item = $mob->getMediaItem("Standard");
2176  $med_areas = $med_item->getMapAreas();
2177 
2178  foreach($med_areas as $area)
2179  {
2180  $link_type = ($area->getLinkType() == "int")
2181  ? "IntLink"
2182  : "ExtLink";
2183 
2184  $areas[] = array(
2185  "Nr" => $area->getNr(),
2186  "Shape" => $area->getShape(),
2187  "Coords" => $area->getCoords(),
2188  "Link" => array(
2189  "LinkType" => $link_type,
2190  "Href" => $area->getHref(),
2191  "Title" => $area->getTitle(),
2192  "Target" => $area->getTarget(),
2193  "Type" => $area->getType(),
2194  "TargetFrame" => $area->getTargetFrame()
2195  )
2196  );
2197 
2198  if ($area->getType() == "PageObject" ||
2199  $area->getType() == "StructureObject")
2200  {
2201  $t = $area->getTarget();
2203  if ($a_from_to[$tid] > 0)
2204  {
2205  $correction_needed = true;
2206  }
2207 //var_dump($a_from_to);
2208  }
2209  }
2210  }
2211  }
2212 
2213  // correct map area links
2214  if ($correction_needed)
2215  {
2216  $changed = true;
2217  $std_alias_item->deleteAllMapAreas();
2218  foreach($areas as $area)
2219  {
2220  if ($area["Link"]["LinkType"] == "IntLink")
2221  {
2222  $target = $area["Link"]["Target"];
2223  $type = $area["Link"]["Type"];
2224  $obj_id = ilInternalLink::_extractObjIdOfTarget($target);
2225  if ($a_from_to[$obj_id] > 0)
2226  {
2227  if ($type == "PageObject" && ilLMObject::_lookupType($a_from_to[$obj_id]) == "pg")
2228  {
2229  $area["Link"]["Target"] = "il__pg_".$a_from_to[$obj_id];
2230  }
2231  if ($type == "StructureObject" && ilLMObject::_lookupType($a_from_to[$obj_id]) == "st")
2232  {
2233  $area["Link"]["Target"] = "il__st_".$a_from_to[$obj_id];
2234  }
2235  }
2236  }
2237 
2238  $std_alias_item->addMapArea($area["Shape"], $area["Coords"],
2239  $area["Link"]["Title"],
2240  array( "Type" => $area["Link"]["Type"],
2241  "TargetFrame" => $area["Link"]["TargetFrame"],
2242  "Target" => $area["Link"]["Target"],
2243  "Href" => $area["Link"]["Href"],
2244  "LinkType" => $area["Link"]["LinkType"],
2245  ));
2246  }
2247  }
2248  }
2249  unset($xpc);
2250 
2251  return $changed;
2252  }
2253 
2259  static function _handleImportRepositoryLinks($a_rep_import_id, $a_rep_type, $a_rep_ref_id)
2260  {
2261  include_once("./Services/COPage/classes/class.ilInternalLink.php");
2262 
2263 //echo "-".$a_rep_import_id."-".$a_rep_ref_id."-";
2264  $sources = ilInternalLink::_getSourcesOfTarget("obj",
2265  ilInternalLink::_extractObjIdOfTarget($a_rep_import_id),
2266  ilInternalLink::_extractInstOfTarget($a_rep_import_id));
2267 //var_dump($sources);
2268  foreach($sources as $source)
2269  {
2270 //echo "A";
2271  if ($source["type"] == "lm:pg")
2272  {
2273 //echo "B";
2274  $page_obj = new ilPageObject("lm", $source["id"], false);
2275  if (!$page_obj->page_not_found)
2276  {
2277 //echo "C";
2278  $page_obj->handleImportRepositoryLink($a_rep_import_id,
2279  $a_rep_type, $a_rep_ref_id);
2280  }
2281  $page_obj->update();
2282  }
2283  }
2284  }
2285 
2286  function handleImportRepositoryLink($a_rep_import_id, $a_rep_type, $a_rep_ref_id)
2287  {
2288  $this->buildDom();
2289 
2290  // resolve normal internal links
2291  $xpc = xpath_new_context($this->dom);
2292  $path = "//IntLink";
2293  $res =& xpath_eval($xpc, $path);
2294 //echo "1";
2295  for($i = 0; $i < count($res->nodeset); $i++)
2296  {
2297 //echo "2";
2298  $target = $res->nodeset[$i]->get_attribute("Target");
2299  $type = $res->nodeset[$i]->get_attribute("Type");
2300  if ($target == $a_rep_import_id && $type == "RepositoryItem")
2301  {
2302 //echo "setting:"."il__".$a_rep_type."_".$a_rep_ref_id;
2303  $res->nodeset[$i]->set_attribute("Target",
2304  "il__".$a_rep_type."_".$a_rep_ref_id);
2305  }
2306  }
2307  unset($xpc);
2308  }
2309 
2313  function createFromXML()
2314  {
2315  global $lng, $ilDB, $ilUser;
2316 
2317 //echo "<br>PageObject::createFromXML[".$this->getId()."]";
2318 
2319  if($this->getXMLContent() == "")
2320  {
2321  $this->setXMLContent("<PageObject></PageObject>");
2322  }
2323 
2324  $iel = $this->containsDeactivatedElements($this->getXMLContent());
2325  $inl = $this->containsIntLinks($this->getXMLContent());
2326 
2327  // create object
2328  /* $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 ".
2329  "(".$ilDB->quote($this->getId()).",".
2330  $ilDB->quote($this->getParentId()).",".
2331  $ilDB->quote($this->getXMLContent()).
2332  ", ".$ilDB->quote($this->getParentType()).
2333  ", ".$ilDB->quote($ilUser->getId()).
2334  ", ".$ilDB->quote($ilUser->getId()).
2335  ", ".$ilDB->quote($iel, "integer")." ".
2336  ", ".$ilDB->quote($inl, "integer")." ".
2337  ", now(), now())"; */
2338 
2339  $ilDB->insert("page_object", array(
2340  "page_id" => array("integer", $this->getId()),
2341  "parent_id" => array("integer", $this->getParentId()),
2342  "content" => array("clob", $this->getXMLContent()),
2343  "parent_type" => array("text", $this->getParentType()),
2344  "create_user" => array("integer", $ilUser->getId()),
2345  "last_change_user" => array("integer", $ilUser->getId()),
2346  "active" => array("integer", $this->getActive()),
2347  "inactive_elements" => array("integer", $iel),
2348  "int_links" => array("integer", $inl),
2349  "created" => array("timestamp", ilUtil::now()),
2350  "last_change" => array("timestamp", ilUtil::now())
2351  ));
2352 
2353 // todo: put this into insert
2354 /* if(!$ilDB->checkQuerySize($query))
2355  {
2356  $this->ilias->raiseError($lng->txt("check_max_allowed_packet_size"),$this->ilias->error_obj->MESSAGE);
2357  return false;
2358  }*/
2359 
2360 // $ilDB->query($query);
2361  }
2362 
2363 
2367  function updateFromXML()
2368  {
2369  global $lng, $ilDB, $ilUser;
2370 
2371 //echo "<br>PageObject::updateFromXML[".$this->getId()."]";
2372 //echo "update:".ilUtil::prepareDBString(($this->getXMLContent())).":<br>";
2373 //echo "update:".htmlentities($this->getXMLContent()).":<br>";
2374 
2375  $iel = $this->containsDeactivatedElements($this->getXMLContent());
2376  $inl = $this->containsIntLinks($this->getXMLContent());
2377 
2378  /*$query = "UPDATE page_object ".
2379  "SET content = ".$ilDB->quote($this->getXMLContent())." ".
2380  ", parent_id = ".$ilDB->quote($this->getParentId())." ".
2381  ", last_change_user = ".$ilDB->quote($ilUser->getId())." ".
2382  ", last_change = now() ".
2383  ", active = ".$ilDB->quote($this->getActive())." ".
2384  ", activation_start = ".$ilDB->quote($this->getActivationStart())." ".
2385  ", activation_end = ".$ilDB->quote($this->getActivationEnd())." ".
2386  ", inactive_elements = ".$ilDB->quote($iel, "integer")." ".
2387  ", int_links = ".$ilDB->quote($inl, "integer")." ".
2388  "WHERE page_id = ".$ilDB->quote($this->getId())." AND parent_type=".
2389  $ilDB->quote($this->getParentType());*/
2390 
2391  $ilDB->update("page_object", array(
2392  "content" => array("clob", $this->getXMLContent()),
2393  "parent_id" => array("integer", $this->getParentId()),
2394  "last_change_user" => array("integer", $ilUser->getId()),
2395  "last_change" => array("timestamp", ilUtil::now()),
2396  "active" => array("integer", $this->getActive()),
2397  "activation_start" => array("timestamp", $this->getActivationStart()),
2398  "activation_end" => array("timestamp", $this->getActivationEnd()),
2399  "inactive_elements" => array("integer", $iel),
2400  "int_links" => array("integer", $inl),
2401  ), array(
2402  "page_id" => array("integer", $this->getId()),
2403  "parent_type" => array("text", $this->getParentType())
2404  ));
2405 
2406 // todo: move this to update
2407 /* if(!$ilDB->checkQuerySize($query))
2408  {
2409  $this->ilias->raiseError($lng->txt("check_max_allowed_packet_size"),$this->ilias->error_obj->MESSAGE);
2410  return false;
2411  }
2412  $ilDB->query($query);*/
2413 // save style usage
2414  $this->saveStyleUsage($this->getXMLContent());
2415 
2416  // save internal link information
2417  $this->saveInternalLinks($this->getXMLContent());
2418  return true;
2419  }
2420 
2424  function update($a_validate = true, $a_no_history = false, $skip_handle_usages = false)
2425  {
2426  global $lng, $ilDB, $ilUser, $ilLog, $ilCtrl;
2427 
2428  $lm_set = new ilSetting("lm");
2429 
2430 //echo "<br>**".$this->getId()."**";
2431 //echo "<br>PageObject::update[".$this->getId()."],validate($a_validate)";
2432 //echo "\n<br>dump_all2:".$this->dom->dump_mem(0, "UTF-8").":";
2433 //echo "\n<br>PageObject::update:".$this->getXMLFromDom().":";
2434 //echo "<br>PageObject::update:".htmlentities($this->getXMLFromDom());
2435 
2436  // add missing pc ids
2437  if (!$this->checkPCIds())
2438  {
2439  $this->insertPCIds();
2440  }
2441 
2442  // test validating
2443  if($a_validate)
2444  {
2445  $errors = $this->validateDom();
2446  }
2447 
2448 //echo "-".htmlentities($this->getXMLFromDom())."-"; exit;
2449  if(empty($errors))
2450  {
2452 
2453  $content = $this->getXMLFromDom();
2454  // this needs to be locked
2455 
2456  // write history entry
2457  $old_set = $ilDB->query("SELECT * FROM page_object WHERE ".
2458  "page_id = ".$ilDB->quote($this->getId(), "integer")." AND ".
2459  "parent_type = ".$ilDB->quote($this->getParentType(), "text"));
2460  $last_nr_set = $ilDB->query("SELECT max(nr) as mnr FROM page_history WHERE ".
2461  "page_id = ".$ilDB->quote($this->getId(), "integer")." AND ".
2462  "parent_type = ".$ilDB->quote($this->getParentType(), "text"));
2463  $last_nr = $ilDB->fetchAssoc($last_nr_set);
2464  if ($old_rec = $ilDB->fetchAssoc($old_set))
2465  {
2466  // only save, if something has changed and not in layout mode
2467  if (($content != $old_rec["content"]) && !$a_no_history &&
2468  !$this->history_saved && !$this->layout_mode &&
2469  $lm_set->get("page_history", 1))
2470  {
2471  if ($old_rec["content"] != "<PageObject></PageObject>")
2472  {
2473  $ilDB->manipulateF("DELETE FROM page_history WHERE ".
2474  "page_id = %s AND parent_type = %s AND hdate = %s",
2475  array("integer", "text", "timestamp"),
2476  array($old_rec["page_id"], $old_rec["parent_type"], $old_rec["last_change"]));
2477 
2478  // the following lines are a workaround for
2479  // bug 6741
2480  $last_c = $old_rec["last_change"];
2481  if ($last_c == "")
2482  {
2483  $last_c = ilUtil::now();
2484  }
2485 
2486  $ilDB->insert("page_history", array(
2487  "page_id" => array("integer", $old_rec["page_id"]),
2488  "parent_type" => array("text", $old_rec["parent_type"]),
2489  "hdate" => array("timestamp", $last_c),
2490  "parent_id" => array("integer", $old_rec["parent_id"]),
2491  "content" => array("clob", $old_rec["content"]),
2492  "user_id" => array("integer", $old_rec["last_change_user"]),
2493  "ilias_version" => array("text", ILIAS_VERSION_NUMERIC),
2494  "nr" => array("integer", (int) $last_nr["mnr"] + 1)
2495  ));
2496  /*$h_query = "REPLACE INTO page_history ".
2497  "(page_id, parent_type, hdate, parent_id, content, user_id, ilias_version, nr) VALUES (".
2498  $ilDB->quote($old_rec["page_id"]).",".
2499  $ilDB->quote($old_rec["parent_type"]).",".
2500  $ilDB->quote($old_rec["last_change"]).",".
2501  $ilDB->quote($old_rec["parent_id"]).",".
2502  $ilDB->quote($old_rec["content"]).",".
2503  $ilDB->quote($old_rec["last_change_user"]).",".
2504  $ilDB->quote(ILIAS_VERSION_NUMERIC).",".
2505  $ilDB->quote($last_nr["mnr"] + 1).")";
2506 //echo "<br><br>+$a_no_history+$h_query";
2507  $ilDB->query($h_query);*/
2508  $this->saveMobUsage($old_rec["content"], $last_nr["mnr"] + 1);
2509  $this->saveStyleUsage($old_rec["content"], $last_nr["mnr"] + 1);
2510  $this->saveFileUsage($old_rec["content"], $last_nr["mnr"] + 1);
2511  $this->saveContentIncludeUsage($old_rec["content"], $last_nr["mnr"] + 1);
2512  $this->saveSkillUsage($old_rec["content"], $last_nr["mnr"] + 1);
2513  $this->history_saved = true; // only save one time
2514  }
2515  else
2516  {
2517  $this->history_saved = true; // do not save on first change
2518  }
2519  }
2520  }
2521 //echo htmlentities($content);
2522  $em = (trim($content) == "<PageObject/>")
2523  ? 1
2524  : 0;
2525 
2526  $iel = $this->containsDeactivatedElements($content);
2527  $inl = $this->containsIntLinks($content);
2528  /*$query = "UPDATE page_object ".
2529  "SET content = ".$ilDB->quote($content)." ".
2530  ", parent_id= ".$ilDB->quote($this->getParentId())." ".
2531  ", last_change_user= ".$ilDB->quote($ilUser->getId())." ".
2532  ", last_change = now() ".
2533  ", is_empty = ".$ilDB->quote($em, "integer")." ".
2534  ", active = ".$ilDB->quote($this->getActive())." ".
2535  ", activation_start = ".$ilDB->quote($this->getActivationStart())." ".
2536  ", activation_end = ".$ilDB->quote($this->getActivationEnd())." ".
2537  ", inactive_elements = ".$ilDB->quote($iel, "integer")." ".
2538  ", int_links = ".$ilDB->quote($inl, "integer")." ".
2539  " WHERE page_id = ".$ilDB->quote($this->getId()).
2540  " AND parent_type= ".$ilDB->quote($this->getParentType());*/
2541 
2542  $ilDB->update("page_object", array(
2543  "content" => array("clob", $content),
2544  "parent_id" => array("integer", $this->getParentId()),
2545  "last_change_user" => array("integer", $ilUser->getId()),
2546  "last_change" => array("timestamp", ilUtil::now()),
2547  "is_empty" => array("integer", $em),
2548  "active" => array("integer", $this->getActive()),
2549  "activation_start" => array("timestamp", $this->getActivationStart()),
2550  "activation_end" => array("timestamp", $this->getActivationEnd()),
2551  "show_activation_info" => array("integer", $this->getShowActivationInfo()),
2552  "inactive_elements" => array("integer", $iel),
2553  "int_links" => array("integer", $inl),
2554  ), array(
2555  "page_id" => array("integer", $this->getId()),
2556  "parent_type" => array("text", $this->getParentType())
2557  ));
2558 
2559 // todo put this into update function
2560 /* if(!$this->ilias->db->checkQuerySize($query))
2561  {
2562  $this->ilias->raiseError($lng->txt("check_max_allowed_packet_size"),$this->ilias->error_obj->MESSAGE);
2563  return false;
2564  }*/
2565 
2566 // $this->ilias->db->query($query);
2567 
2568  if (!$skip_handle_usages)
2569  {
2570  // handle media object usage
2571  include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
2573  $this->getParentType().":pg", $this->getId());
2574  $this->saveMobUsage($this->getXMLFromDom());
2575  $this->saveMetaKeywords($this->getXMLFromDom());
2576  foreach($mob_ids as $mob) // check, whether media object can be deleted
2577  {
2578  if (ilObject::_exists($mob) && ilObject::_lookupType($mob) == "mob")
2579  {
2580  $mob_obj = new ilObjMediaObject($mob);
2581  $usages = $mob_obj->getUsages(false);
2582  if (count($usages) == 0) // delete, if no usage exists
2583  {
2584  $mob_obj->delete();
2585  }
2586  }
2587  }
2588 
2589  // handle file usages
2590  include_once("./Modules/File/classes/class.ilObjFile.php");
2591  $file_ids = ilObjFile::_getFilesOfObject(
2592  $this->getParentType().":pg", $this->getId());
2593  $this->saveFileUsage();
2594  foreach($file_ids as $file) // check, whether file object can be deleted
2595  {
2596  if (ilObject::_exists($file))
2597  {
2598  $file_obj = new ilObjFile($file, false);
2599  $usages = $file_obj->getUsages();
2600  if (count($usages) == 0) // delete, if no usage exists
2601  {
2602  if ($file_obj->getMode() == "filelist") // non-repository object
2603  {
2604  $file_obj->delete();
2605  }
2606  }
2607  }
2608  }
2609 
2610  // save style usage
2611  $this->saveStyleUsage($this->getXMLFromDom());
2612 
2613  // save content include usage
2614  $this->saveContentIncludeUsage($this->getXMLFromDom());
2615  $this->saveSkillUsage($this->getXMLFromDom());
2616  }
2617 
2618  // save internal link information
2619  $this->saveInternalLinks($this->getXMLFromDom());
2620  $this->saveAnchors($this->getXMLFromDom());
2621  $this->callUpdateListeners();
2622 //echo "<br>PageObject::update:".htmlentities($this->getXMLContent()).":";
2623  return true;
2624  }
2625  else
2626  {
2627  return $errors;
2628  }
2629  }
2630 
2631 
2635  function delete()
2636  {
2637  global $ilDB;
2638 
2639  $mobs = array();
2640  $files = array();
2641 
2642  if (!$this->page_not_found)
2643  {
2644  $this->buildDom();
2645  $mobs = $this->collectMediaObjects(false);
2646  $files = $this->collectFileItems();
2647  }
2648 
2649  // delete mob usages
2650  $this->saveMobUsage("<dummy></dummy>");
2651 
2652  // delete style usages
2653  $this->saveStyleUsage("<dummy></dummy>");
2654 
2655  // delete style usages
2656  $this->saveContentIncludeUsage("<dummy></dummy>");
2657  $this->saveSkillUsage("<dummy></dummy>");
2658 
2659  // delete internal links
2660  $this->saveInternalLinks("<dummy></dummy>");
2661 
2662  // delete anchors
2663  $this->saveAnchors("<dummy></dummy>");
2664 
2665  // delete all file usages
2666  include_once("./Modules/File/classes/class.ilObjFile.php");
2667  ilObjFile::_deleteAllUsages($this->getParentType().":pg", $this->getId());
2668 
2669  // delete news
2670  include_once("./Services/News/classes/class.ilNewsItem.php");
2672  $this->getParentType(), $this->getId(), "pg");
2673 
2674  // delete page_object entry
2675  $ilDB->manipulate("DELETE FROM page_object ".
2676  "WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
2677  " AND parent_type= ".$ilDB->quote($this->getParentType(), "text"));
2678  //$this->ilias->db->query($query);
2679 
2680  // delete media objects
2681  foreach ($mobs as $mob_id)
2682  {
2683  if(ilObject::_lookupType($mob_id) != 'mob')
2684  {
2685  $GLOBALS['ilLog']->write(__METHOD__.': Type mismatch. Ignoring mob with id: '.$mob_id);
2686  continue;
2687  }
2688 
2689  if (ilObject::_exists($mob_id))
2690  {
2691  $mob_obj =& new ilObjMediaObject($mob_id);
2692  $mob_obj->delete();
2693  }
2694  }
2695 
2696  include_once("./Modules/File/classes/class.ilObjFile.php");
2697  foreach ($files as $file_id)
2698  {
2699  if (ilObject::_exists($file_id))
2700  {
2701  $file_obj =& new ilObjFile($file_id, false);
2702  $file_obj->delete();
2703  }
2704  }
2705 
2706  /* delete public and private notes (see PageObjectGUI->getNotesHTML())
2707  as they can be seen as personal data we are keeping them for now
2708  include_once("Services/Notes/classes/class.ilNote.php");
2709  foreach(array(IL_NOTE_PRIVATE, IL_NOTE_PUBLIC) as $note_type)
2710  {
2711  foreach(ilNote::_getNotesOfObject($this->getParentId(), $this->getId(),
2712  $this->getParentType(), $note_type) as $note)
2713  {
2714  $note->delete();
2715  }
2716  }
2717  */
2718  }
2719 
2725  function saveMetaKeywords($a_xml)
2726  {
2727  // not nice, should be set by context per method
2728  if ($this->getParentType() == "gdf" ||
2729  $this->getParentType() == "lm" ||
2730  $this->getParentType() == "dbk")
2731  {
2732  $doc = domxml_open_mem($a_xml);
2733 
2734  // get existing keywords
2735  $keywords = array();
2736 
2737  // find all Keyw tags
2738  $xpc = xpath_new_context($doc);
2739  $path = "//Keyw";
2740  $res = xpath_eval($xpc, $path);
2741  for ($i=0; $i < count($res->nodeset); $i++)
2742  {
2743  $k = trim(strip_tags($res->nodeset[$i]->get_content()));
2744  if (!in_array($k, $keywords))
2745  {
2746  $keywords[] = $k;
2747  }
2748  }
2749 
2750  $meta_type = ($this->getParentType() == "gdf")
2751  ? "gdf"
2752  : "pg";
2753  $meta_rep_id = $this->getParentId();
2754  $meta_id = $this->getId();
2755 
2756  include_once("./Services/MetaData/classes/class.ilMD.php");
2757  $md_obj = new ilMD($meta_rep_id, $meta_id, $meta_type);
2758  $mkeywords = array();
2759  $lang = "";
2760  if(is_object($md_section = $md_obj->getGeneral()))
2761  {
2762  foreach($ids = $md_section->getKeywordIds() as $id)
2763  {
2764  $md_key = $md_section->getKeyword($id);
2765  $mkeywords[] = strtolower($md_key->getKeyword());
2766  if ($lang == "")
2767  {
2768  $lang = $md_key->getKeywordLanguageCode();
2769  }
2770  }
2771  }
2772  if ($lang == "")
2773  {
2774  foreach($ids = $md_section->getLanguageIds() as $id)
2775  {
2776  $md_lang = $md_section->getLanguage($id);
2777  if ($lang == "")
2778  {
2779  $lang = $md_lang->getLanguageCode();
2780  }
2781  }
2782  }
2783  foreach ($keywords as $k)
2784  {
2785  if (!in_array(strtolower($k), $mkeywords))
2786  {
2787  if (trim($k) != "" && $lang != "")
2788  {
2789  $md_key = $md_section->addKeyword();
2790  $md_key->setKeyword(ilUtil::stripSlashes($k));
2791  $md_key->setKeywordLanguage(new ilMDLanguageItem($lang));
2792  $md_key->save();
2793  }
2794  $mkeywords[] = strtolower($k);
2795  }
2796  }
2797  }
2798  }
2799 
2805  function saveMobUsage($a_xml, $a_old_nr = 0)
2806  {
2807  $doc = domxml_open_mem($a_xml);
2808 
2809  // media aliases
2810  $xpc = xpath_new_context($doc);
2811  $path = "//MediaAlias";
2812  $res =& xpath_eval($xpc, $path);
2813  $usages = array();
2814  for ($i=0; $i < count($res->nodeset); $i++)
2815  {
2816  $id_arr = explode("_", $res->nodeset[$i]->get_attribute("OriginId"));
2817  $mob_id = $id_arr[count($id_arr) - 1];
2818  if ($mob_id > 0)
2819  {
2820  $usages[$mob_id] = true;
2821  }
2822  }
2823 
2824  // media objects
2825  $xpc = xpath_new_context($doc);
2826  $path = "//MediaObject/MetaData/General/Identifier";
2827  $res =& xpath_eval($xpc, $path);
2828  for ($i=0; $i < count($res->nodeset); $i++)
2829  {
2830  $mob_entry = $res->nodeset[$i]->get_attribute("Entry");
2831  $mob_arr = explode("_", $mob_entry);
2832  $mob_id = $mob_arr[count($mob_arr) - 1];
2833  if ($mob_id > 0)
2834  {
2835  $usages[$mob_id] = true;
2836  }
2837  }
2838 
2839  // internal links
2840  $xpc = xpath_new_context($doc);
2841  $path = "//IntLink[@Type='MediaObject']";
2842  $res =& xpath_eval($xpc, $path);
2843  for ($i=0; $i < count($res->nodeset); $i++)
2844  {
2845  $mob_target = $res->nodeset[$i]->get_attribute("Target");
2846  $mob_arr = explode("_", $mob_target);
2847  $mob_id = $mob_arr[count($mob_arr) - 1];
2848  if ($mob_id > 0)
2849  {
2850  $usages[$mob_id] = true;
2851  }
2852  }
2853 
2854  include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
2855  ilObjMediaObject::_deleteAllUsages($this->getParentType().":pg", $this->getId(), $a_old_nr);
2856  foreach($usages as $mob_id => $val)
2857  {
2858  ilObjMediaObject::_saveUsage($mob_id, $this->getParentType().":pg", $this->getId(), $a_old_nr);
2859  }
2860 
2861  return $usages;
2862  }
2863 
2867  function saveFileUsage($a_xml = "", $a_old_nr = 0)
2868  {
2869  $file_ids = $this->collectFileItems($a_xml, $a_old_nr);
2870  include_once("./Modules/File/classes/class.ilObjFile.php");
2871  ilObjFile::_deleteAllUsages($this->getParentType().":pg", $this->getId(), $a_old_nr);
2872  foreach($file_ids as $file_id)
2873  {
2874  ilObjFile::_saveUsage($file_id, $this->getParentType().":pg", $this->getId(), $a_old_nr);
2875  }
2876  }
2877 
2881  function saveContentIncludeUsage($a_xml = "", $a_old_nr = 0)
2882  {
2883  include_once("./Services/COPage/classes/class.ilPageContentUsage.php");
2884  $ci_ids = $this->collectContentIncludes($a_xml);
2885  ilPageContentUsage::deleteAllUsages("incl", $this->getParentType().":pg", $this->getId(), $a_old_nr);
2886  foreach($ci_ids as $ci_id)
2887  {
2888  if ((int) $ci_id["inst_id"] <= 0)
2889  {
2890  ilPageContentUsage::saveUsage("incl", $ci_id["id"], $this->getParentType().":pg", $this->getId(), $a_old_nr);
2891  }
2892  }
2893  }
2894 
2898  function collectContentIncludes($a_xml = "")
2899  {
2900  // determine all media aliases of the page
2901  if ($a_xml == "")
2902  {
2903  $this->buildDom();
2904  $xpc = xpath_new_context($this->dom);
2905  $path = "//ContentInclude";
2906  $res =& xpath_eval($xpc, $path);
2907  }
2908  else
2909  {
2910  $doc = domxml_open_mem($a_xml);
2911  $xpc = xpath_new_context($doc);
2912  $path = "//ContentInclude";
2913  $res =& xpath_eval($xpc, $path);
2914  }
2915  $ci_ids = array();
2916  for($i = 0; $i < count($res->nodeset); $i++)
2917  {
2918  $type = $res->nodeset[$i]->get_attribute("ContentType");
2919  $id = $res->nodeset[$i]->get_attribute("ContentId");
2920  $inst_id = $res->nodeset[$i]->get_attribute("InstId");
2921  $ci_ids[$type.":".$id.":".$inst_id] = array(
2922  "type" => $type, "id" => $id, "inst_id" => $inst_id);
2923  }
2924 
2925  return $ci_ids;
2926  }
2927 
2931  function saveSkillUsage($a_xml = "", $a_old_nr = 0)
2932  {
2933  include_once("./Services/COPage/classes/class.ilPageContentUsage.php");
2934  $skl_ids = $this->collectSkills($a_xml);
2935  ilPageContentUsage::deleteAllUsages("skmg", $this->getParentType().":pg", $this->getId(), $a_old_nr);
2936  foreach($skl_ids as $skl_id)
2937  {
2938  if ((int) $skl_id["inst_id"] <= 0)
2939  {
2940  ilPageContentUsage::saveUsage("skmg", $skl_id["id"], $this->getParentType().":pg", $this->getId(), $a_old_nr);
2941  }
2942  }
2943  }
2944 
2948  function collectSkills($a_xml = "")
2949  {
2950  // determine all media aliases of the page
2951  if ($a_xml == "")
2952  {
2953  $this->buildDom();
2954  $xpc = xpath_new_context($this->dom);
2955  $path = "//Skills";
2956  $res =& xpath_eval($xpc, $path);
2957  }
2958  else
2959  {
2960  $doc = domxml_open_mem($a_xml);
2961  $xpc = xpath_new_context($doc);
2962  $path = "//Skills";
2963  $res =& xpath_eval($xpc, $path);
2964  }
2965  $skl_ids = array();
2966  for($i = 0; $i < count($res->nodeset); $i++)
2967  {
2968  $user = $res->nodeset[$i]->get_attribute("User");
2969  $id = $res->nodeset[$i]->get_attribute("Id");
2970  $inst_id = $res->nodeset[$i]->get_attribute("InstId");
2971  $skl_ids[$user.":".$id.":".$inst_id] = array(
2972  "user" => $user, "id" => $id, "inst_id" => $inst_id);
2973  }
2974 
2975  return $skl_ids;
2976  }
2977 
2978 
2984  function saveStyleUsage($a_xml, $a_old_nr = 0)
2985  {
2986  global $ilDB;
2987 
2988  $doc = domxml_open_mem($a_xml);
2989 
2990  // media aliases
2991  $xpc = xpath_new_context($doc);
2992  $path = "//Paragraph | //Section | //MediaAlias | //FileItem".
2993  " | //Table | //TableData | //Tabs | //List";
2994  $res = xpath_eval($xpc, $path);
2995  $usages = array();
2996  for ($i=0; $i < count($res->nodeset); $i++)
2997  {
2998  switch ($res->nodeset[$i]->node_name())
2999  {
3000  case "Paragraph":
3001  $sname = $res->nodeset[$i]->get_attribute("Characteristic");
3002  $stype = "text_block";
3003  $template = 0;
3004  break;
3005 
3006  case "Section":
3007  $sname = $res->nodeset[$i]->get_attribute("Characteristic");
3008  $stype = "section";
3009  $template = 0;
3010  break;
3011 
3012  case "MediaAlias":
3013  $sname = $res->nodeset[$i]->get_attribute("Class");
3014  $stype = "media_cont";
3015  $template = 0;
3016  break;
3017 
3018  case "FileItem":
3019  $sname = $res->nodeset[$i]->get_attribute("Class");
3020  $stype = "flist_li";
3021  $template = 0;
3022  break;
3023 
3024  case "Table":
3025  $sname = $res->nodeset[$i]->get_attribute("Template");
3026  if ($sname == "")
3027  {
3028  $sname = $res->nodeset[$i]->get_attribute("Class");
3029  $stype = "table";
3030  $template = 0;
3031  }
3032  else
3033  {
3034  $stype = "table";
3035  $template = 1;
3036  }
3037  break;
3038 
3039  case "TableData":
3040  $sname = $res->nodeset[$i]->get_attribute("Class");
3041  $stype = "table_cell";
3042  $template = 0;
3043  break;
3044 
3045  case "Tabs":
3046  $sname = $res->nodeset[$i]->get_attribute("Template");
3047  if ($sname != "")
3048  {
3049  if ($res->nodeset[$i]->get_attribute("Type") == "HorizontalAccordion")
3050  {
3051  $stype = "haccordion";
3052  }
3053  if ($res->nodeset[$i]->get_attribute("Type") == "VerticalAccordion")
3054  {
3055  $stype = "vaccordion";
3056  }
3057  }
3058  $template = 1;
3059  break;
3060 
3061  case "List":
3062  $sname = $res->nodeset[$i]->get_attribute("Class");
3063  if ($res->nodeset[$i]->get_attribute("Type") == "Ordered")
3064  {
3065  $stype = "list_o";
3066  }
3067  else
3068  {
3069  $stype = "list_u";
3070  }
3071  $template = 0;
3072  break;
3073  }
3074  if ($sname != "" && $stype != "")
3075  {
3076  $usages[$sname.":".$stype.":".$template] = array("sname" => $sname,
3077  "stype" => $stype, "template" => $template);
3078  }
3079  }
3080 
3081  $ilDB->manipulate("DELETE FROM page_style_usage WHERE ".
3082  " page_id = ".$ilDB->quote($this->getId(), "integer").
3083  " AND page_type = ".$ilDB->quote($this->getParentType(), "text").
3084  " AND page_nr = ".$ilDB->quote($a_old_nr, "integer")
3085  );
3086 
3087  foreach ($usages as $u)
3088  {
3089  $ilDB->manipulate("INSERT INTO page_style_usage ".
3090  "(page_id, page_type, page_nr, template, stype, sname) VALUES (".
3091  $ilDB->quote($this->getId(), "integer").",".
3092  $ilDB->quote($this->getParentType(), "text").",".
3093  $ilDB->quote($a_old_nr, "integer").",".
3094  $ilDB->quote($u["template"], "integer").",".
3095  $ilDB->quote($u["stype"], "text").",".
3096  $ilDB->quote($u["sname"], "text").
3097  ")");
3098  }
3099  }
3100 
3106  {
3107  include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
3108  include_once("./Modules/File/classes/class.ilObjFile.php");
3110  $this->getId());
3111  $files = ilObjFile::_getFilesOfObject($this->getParentType().":pg",
3112  $this->getId());
3113  $objs = array_merge($mobs, $files);
3114  return ilObject::_getLastUpdateOfObjects($objs);
3115  }
3116 
3122  function saveInternalLinks($a_xml)
3123  {
3124  global $ilDB;
3125 
3126 //echo "<br>PageObject::saveInternalLinks[".$this->getId()."]";
3127  $doc = domxml_open_mem($a_xml);
3128 
3129 
3130  include_once("./Services/COPage/classes/class.ilInternalLink.php");
3132 
3133  // get all internal links
3134  $xpc = xpath_new_context($doc);
3135  $path = "//IntLink";
3136  $res =& xpath_eval($xpc, $path);
3137  for ($i=0; $i < count($res->nodeset); $i++)
3138  {
3139  $link_type = $res->nodeset[$i]->get_attribute("Type");
3140 
3141  switch ($link_type)
3142  {
3143  case "StructureObject":
3144  $t_type = "st";
3145  break;
3146 
3147  case "PageObject":
3148  $t_type = "pg";
3149  break;
3150 
3151  case "GlossaryItem":
3152  $t_type = "git";
3153  break;
3154 
3155  case "MediaObject":
3156  $t_type = "mob";
3157  break;
3158 
3159  case "RepositoryItem":
3160  $t_type = "obj";
3161  break;
3162 
3163  case "File":
3164  $t_type = "file";
3165  break;
3166  }
3167 
3168  $target = $res->nodeset[$i]->get_attribute("Target");
3169  $target_arr = explode("_", $target);
3170  $t_id = $target_arr[count($target_arr) - 1];
3171 
3172  // link to other internal object
3173  if (is_int(strpos($target, "__")))
3174  {
3175  $t_inst = 0;
3176  }
3177  else // link to unresolved object in other installation
3178  {
3179  $t_inst = $target_arr[1];
3180  }
3181 
3182  if ($t_id > 0)
3183  {
3184  ilInternalLink::_saveLink($this->getParentType().":pg", $this->getId(), $t_type,
3185  $t_id, $t_inst);
3186  }
3187  }
3188 
3189  // *** STEP 2: Save question references of page ***
3190 
3191  // delete all reference records
3192  $ilDB->manipulateF("DELETE FROM page_question WHERE page_parent_type = %s ".
3193  " AND page_id = %s", array("text", "integer"),
3194  array($this->getParentType(), $this->getId()));
3195 
3196  // save question references of page
3197  $doc = domxml_open_mem($a_xml);
3198  $xpc = xpath_new_context($doc);
3199  $path = "//Question";
3200  $res = xpath_eval($xpc, $path);
3201  $q_ids = array();
3202  for ($i=0; $i < count($res->nodeset); $i++)
3203  {
3204  $q_ref = $res->nodeset[$i]->get_attribute("QRef");
3205 
3206  $inst_id = ilInternalLink::_extractInstOfTarget($q_ref);
3207  if (!($inst_id > 0))
3208  {
3209  $q_id = ilInternalLink::_extractObjIdOfTarget($q_ref);
3210  if ($q_id > 0)
3211  {
3212  $q_ids[$q_id] = $q_id;
3213  }
3214  }
3215  }
3216  foreach($q_ids as $qid)
3217  {
3218  $ilDB->manipulateF("INSERT INTO page_question (page_parent_type, page_id, question_id)".
3219  " VALUES (%s,%s,%s)",
3220  array("text", "integer", "integer"),
3221  array($this->getParentType(), $this->getId(), $qid));
3222  }
3223  }
3224 
3228  static function _getQuestionIdsForPage($a_parent_type, $a_page_id)
3229  {
3230  global $ilDB;
3231 
3232  $res = $ilDB->queryF("SELECT * FROM page_question WHERE page_parent_type = %s ".
3233  " AND page_id = %s",
3234  array("text", "integer"),
3235  array($a_parent_type, $a_page_id));
3236  $q_ids = array();
3237  while ($rec = $ilDB->fetchAssoc($res))
3238  {
3239  $q_ids[] = $rec["question_id"];
3240  }
3241 
3242  return $q_ids;
3243  }
3244 
3250  function saveAnchors($a_xml)
3251  {
3252  $doc = domxml_open_mem($a_xml);
3253 
3254  ilPageObject::_deleteAnchors($this->getParentType(), $this->getId());
3255 
3256  // get all anchors
3257  $xpc = xpath_new_context($doc);
3258  $path = "//Anchor";
3259  $res =& xpath_eval($xpc, $path);
3260  $saved = array();
3261  for ($i=0; $i < count($res->nodeset); $i++)
3262  {
3263  $name = $res->nodeset[$i]->get_attribute("Name");
3264  if (trim($name) != "" && !in_array($name, $saved))
3265  {
3266  ilPageObject::_saveAnchor($this->getParentType(), $this->getId(), $name);
3267  $saved[] = $name;
3268  }
3269  }
3270 
3271  }
3272 
3276  static function _deleteAnchors($a_parent_type, $a_page_id)
3277  {
3278  global $ilDB;
3279 
3280  $st = $ilDB->prepareManip("DELETE FROM page_anchor WHERE page_parent_type = ? ".
3281  " AND page_id = ?", array("text", "integer"));
3282  $ilDB->execute($st, array($a_parent_type, $a_page_id));
3283  }
3284 
3288  static function _saveAnchor($a_parent_type, $a_page_id, $a_anchor_name)
3289  {
3290  global $ilDB;
3291 
3292  $st = $ilDB->prepareManip("INSERT INTO page_anchor (page_parent_type, page_id, anchor_name) ".
3293  " VALUES (?,?,?) ", array("text", "integer", "text"));
3294  $ilDB->execute($st, array($a_parent_type, $a_page_id, $a_anchor_name));
3295  }
3296 
3300  static function _readAnchors($a_parent_type, $a_page_id)
3301  {
3302  global $ilDB;
3303 
3304  $st = $ilDB->prepare("SELECT * FROM page_anchor WHERE page_parent_type = ? ".
3305  " AND page_id = ?", array("text", "integer"));
3306  $set = $ilDB->execute($st, array($a_parent_type, $a_page_id));
3307  $anchors = array();
3308  while ($rec = $ilDB->fetchAssoc($set))
3309  {
3310  $anchors[] = $rec["anchor_name"];
3311  }
3312  return $anchors;
3313  }
3314 
3318  function create()
3319  {
3320  $this->createFromXML();
3321  }
3322 
3330  function deleteContent($a_hid, $a_update = true, $a_pcid = "")
3331  {
3332  $curr_node =& $this->getContentNode($a_hid, $a_pcid);
3333  $curr_node->unlink_node($curr_node);
3334  if ($a_update)
3335  {
3336  return $this->update();
3337  }
3338  }
3339 
3340 
3348  function deleteContents($a_hids, $a_update = true, $a_self_ass = false)
3349  {
3350  if (!is_array($a_hids))
3351  {
3352  return;
3353  }
3354  foreach($a_hids as $a_hid)
3355  {
3356  $a_hid = explode(":", $a_hid);
3357 //echo "-".$a_hid[0]."-".$a_hid[1]."-";
3358 
3359  // do not delete question nodes in assessment pages
3360  if (!$this->checkForTag("Question", $a_hid[0], $a_hid[1]) || $a_self_ass)
3361  {
3362  $curr_node =& $this->getContentNode($a_hid[0], $a_hid[1]);
3363  if (is_object($curr_node))
3364  {
3365  $parent_node = $curr_node->parent_node();
3366  if ($parent_node->node_name() != "TableRow")
3367  {
3368  $curr_node->unlink_node($curr_node);
3369  }
3370  }
3371  }
3372  }
3373  if ($a_update)
3374  {
3375  return $this->update();
3376  }
3377  }
3378 
3384  function cutContents($a_hids)
3385  {
3386  $this->copyContents($a_hids);
3387  return $this->deleteContents($a_hids);
3388  }
3389 
3395  function copyContents($a_hids)
3396  {
3397  global $ilUser;
3398 //var_dump($a_hids);
3399  if (!is_array($a_hids))
3400  {
3401  return;
3402  }
3403 
3404  $time = date("Y-m-d H:i:s", time());
3405 
3406  $hier_ids = array();
3407  $skip = array();
3408  foreach($a_hids as $a_hid)
3409  {
3410  if ($a_hid == "")
3411  {
3412  continue;
3413  }
3414  $a_hid = explode(":", $a_hid);
3415 
3416  // check, whether new hid is child of existing one or vice versa
3417  reset($hier_ids);
3418  foreach($hier_ids as $h)
3419  {
3420  if($h."_" == substr($a_hid[0], 0, strlen($h) + 1))
3421  {
3422  $skip[] = $a_hid[0];
3423  }
3424  if($a_hid[0]."_" == substr($h, 0, strlen($a_hid[0]) + 1))
3425  {
3426  $skip[] = $h;
3427  }
3428  }
3429  $pc_id[$a_hid[0]] = $a_hid[1];
3430  if ($a_hid[0] != "")
3431  {
3432  $hier_ids[$a_hid[0]] = $a_hid[0];
3433  }
3434  }
3435  foreach ($skip as $s)
3436  {
3437  unset($hier_ids[$s]);
3438  }
3439  include_once("./Services/COPage/classes/class.ilPageContent.php");
3440  $hier_ids = ilPageContent::sortHierIds($hier_ids);
3441  $nr = 1;
3442  foreach($hier_ids as $hid)
3443  {
3444  $curr_node = $this->getContentNode($hid, $pc_id[$hid]);
3445  if (is_object($curr_node))
3446  {
3447  if ($curr_node->node_name() == "PageContent")
3448  {
3449  $content = $this->dom->dump_node($curr_node);
3450  // remove pc and hier ids
3451  $content = eregi_replace("PCID=\"[a-z0-9]*\"","",$content);
3452  $content = eregi_replace("HierId=\"[a-z0-9_]*\"","",$content);
3453 
3454  $ilUser->addToPCClipboard($content, $time, $nr);
3455  $nr++;
3456  }
3457  }
3458  }
3459  include_once("./Modules/LearningModule/classes/class.ilEditClipboard.php");
3461  }
3462 
3466  function pasteContents($a_hier_id, $a_self_ass = false)
3467  {
3468  global $ilUser;
3469 
3470  $a_hid = explode(":", $a_hier_id);
3471  $content = $ilUser->getPCClipboardContent();
3472 
3473  // we insert from last to first, because we insert all at the
3474  // same hier_id
3475  for ($i = count($content) - 1; $i >= 0; $i--)
3476  {
3477 
3478  $c = $content[$i];
3479  $temp_dom = domxml_open_mem('<?xml version="1.0" encoding="UTF-8"?>'.$c,
3480  DOMXML_LOAD_PARSING, $error);
3481  if(empty($error))
3482  {
3483  $this->handleCopiedContent($temp_dom, $a_self_ass);
3484  $xpc = xpath_new_context($temp_dom);
3485  $path = "//PageContent";
3486  $res = xpath_eval($xpc, $path);
3487  if (count($res->nodeset) > 0)
3488  {
3489  $new_pc_node = $res->nodeset[0];
3490  $cloned_pc_node = $new_pc_node->clone_node (true);
3491  $cloned_pc_node->unlink_node ($cloned_pc_node);
3492  $this->insertContentNode ($cloned_pc_node, $a_hid[0],
3493  IL_INSERT_AFTER, $a_hid[1]);
3494  }
3495  }
3496  else
3497  {
3498 //var_dump($error);
3499  }
3500  }
3501  $e = $this->update();
3502 //var_dump($e);
3503  }
3504 
3508  function switchEnableMultiple($a_hids, $a_update = true, $a_self_ass = false)
3509  {
3510  if (!is_array($a_hids))
3511  {
3512  return;
3513  }
3514  $obj = & $this->content_obj;
3515 
3516  foreach($a_hids as $a_hid)
3517  {
3518  $a_hid = explode(":", $a_hid);
3519  $curr_node =& $this->getContentNode($a_hid[0], $a_hid[1]);
3520  if (is_object($curr_node))
3521  {
3522  if ($curr_node->node_name() == "PageContent")
3523  {
3524  $cont_obj =& $this->getContentObject($a_hid[0], $a_hid[1]);
3525  if ($cont_obj->isEnabled ())
3526  {
3527  // do not deactivate question nodes in assessment pages
3528  if (!$this->checkForTag("Question", $a_hid[0], $a_hid[1]) || $a_self_ass)
3529  {
3530  $cont_obj->disable();
3531  }
3532  }
3533  else
3534  {
3535  $cont_obj->enable();
3536  }
3537  }
3538  }
3539  }
3540 
3541  if ($a_update)
3542  {
3543  return $this->update();
3544  }
3545  }
3546 
3547 
3555  function deleteContentFromHierId($a_hid, $a_update = true)
3556  {
3557  $hier_ids = $this->getHierIds();
3558 
3559  // iterate all hierarchical ids
3560  foreach ($hier_ids as $hier_id)
3561  {
3562  // delete top level nodes only
3563  if (!is_int(strpos($hier_id, "_")))
3564  {
3565  if ($hier_id != "pg" && $hier_id >= $a_hid)
3566  {
3567  $curr_node =& $this->getContentNode($hier_id);
3568  $curr_node->unlink_node($curr_node);
3569  }
3570  }
3571  }
3572  if ($a_update)
3573  {
3574  return $this->update();
3575  }
3576  }
3577 
3585  function deleteContentBeforeHierId($a_hid, $a_update = true)
3586  {
3587  $hier_ids = $this->getHierIds();
3588 
3589  // iterate all hierarchical ids
3590  foreach ($hier_ids as $hier_id)
3591  {
3592  // delete top level nodes only
3593  if (!is_int(strpos($hier_id, "_")))
3594  {
3595  if ($hier_id != "pg" && $hier_id < $a_hid)
3596  {
3597  $curr_node =& $this->getContentNode($hier_id);
3598  $curr_node->unlink_node($curr_node);
3599  }
3600  }
3601  }
3602  if ($a_update)
3603  {
3604  return $this->update();
3605  }
3606  }
3607 
3608 
3616  function _moveContentAfterHierId(&$a_source_page, &$a_target_page, $a_hid)
3617  {
3618  $hier_ids = $a_source_page->getHierIds();
3619 
3620  $copy_ids = array();
3621 
3622  // iterate all hierarchical ids
3623  foreach ($hier_ids as $hier_id)
3624  {
3625  // move top level nodes only
3626  if (!is_int(strpos($hier_id, "_")))
3627  {
3628  if ($hier_id != "pg" && $hier_id >= $a_hid)
3629  {
3630  $copy_ids[] = $hier_id;
3631  }
3632  }
3633  }
3634  asort($copy_ids);
3635 
3636  $parent_node =& $a_target_page->getContentNode("pg");
3637  $target_dom =& $a_target_page->getDom();
3638  $parent_childs =& $parent_node->child_nodes();
3639  $cnt_parent_childs = count($parent_childs);
3640 //echo "-$cnt_parent_childs-";
3641  $first_child =& $parent_childs[0];
3642  foreach($copy_ids as $copy_id)
3643  {
3644  $source_node =& $a_source_page->getContentNode($copy_id);
3645 
3646  $new_node =& $source_node->clone_node(true);
3647  $new_node->unlink_node($new_node);
3648 
3649  $source_node->unlink_node($source_node);
3650 
3651  if($cnt_parent_childs == 0)
3652  {
3653  $new_node =& $parent_node->append_child($new_node);
3654  }
3655  else
3656  {
3657  //$target_dom->import_node($new_node);
3658  $new_node =& $first_child->insert_before($new_node, $first_child);
3659  }
3660  $parent_childs =& $parent_node->child_nodes();
3661 
3662  //$cnt_parent_childs++;
3663  }
3664 
3665  $a_target_page->update();
3666  $a_source_page->update();
3667 
3668  }
3669 
3673  function insertContent(&$a_cont_obj, $a_pos, $a_mode = IL_INSERT_AFTER, $a_pcid = "")
3674  {
3675 //echo "-".$a_pos."-".$a_pcid."-";
3676  // move mode into container elements is always INSERT_CHILD
3677  $curr_node = $this->getContentNode($a_pos, $a_pcid);
3678  $curr_name = $curr_node->node_name();
3679  if (($curr_name == "TableData") || ($curr_name == "PageObject") ||
3680  ($curr_name == "ListItem") || ($curr_name == "Section")
3681  || ($curr_name == "Tab") || ($curr_name == "ContentPopup"))
3682  {
3683  $a_mode = IL_INSERT_CHILD;
3684  }
3685 
3686  $hid = $curr_node->get_attribute("HierId");
3687  if ($hid != "")
3688  {
3689 //echo "-".$a_pos."-".$hid."-";
3690  $a_pos = $hid;
3691  }
3692 
3693  if($a_mode != IL_INSERT_CHILD) // determine parent hierarchical id
3694  { // of sibling at $a_pos
3695  $pos = explode("_", $a_pos);
3696  $target_pos = array_pop($pos);
3697  $parent_pos = implode($pos, "_");
3698  }
3699  else // if we should insert a child, $a_pos is alreade the hierarchical id
3700  { // of the parent node
3701  $parent_pos = $a_pos;
3702  }
3703 
3704  // get the parent node
3705  if($parent_pos != "")
3706  {
3707  $parent_node =& $this->getContentNode($parent_pos);
3708  }
3709  else
3710  {
3711  $parent_node =& $this->getNode();
3712  }
3713 
3714  // count the parent children
3715  $parent_childs =& $parent_node->child_nodes();
3716  $cnt_parent_childs = count($parent_childs);
3717 //echo "ZZ$a_mode";
3718  switch ($a_mode)
3719  {
3720  // insert new node after sibling at $a_pos
3721  case IL_INSERT_AFTER:
3722  $new_node =& $a_cont_obj->getNode();
3723  //$a_pos = ilPageContent::incEdId($a_pos);
3724  //$curr_node =& $this->getContentNode($a_pos);
3725 //echo "behind $a_pos:";
3726  if($succ_node =& $curr_node->next_sibling())
3727  {
3728  $new_node =& $succ_node->insert_before($new_node, $succ_node);
3729  }
3730  else
3731  {
3732 //echo "movin doin append_child";
3733  $new_node =& $parent_node->append_child($new_node);
3734  }
3735  $a_cont_obj->setNode($new_node);
3736  break;
3737 
3738  case IL_INSERT_BEFORE:
3739 //echo "INSERT_BEF";
3740  $new_node =& $a_cont_obj->getNode();
3741  $succ_node =& $this->getContentNode($a_pos);
3742  $new_node =& $succ_node->insert_before($new_node, $succ_node);
3743  $a_cont_obj->setNode($new_node);
3744  break;
3745 
3746  // insert new node as first child of parent $a_pos (= $a_parent)
3747  case IL_INSERT_CHILD:
3748 //echo "insert as child:parent_childs:$cnt_parent_childs:<br>";
3749  $new_node =& $a_cont_obj->getNode();
3750  if($cnt_parent_childs == 0)
3751  {
3752  $new_node =& $parent_node->append_child($new_node);
3753  }
3754  else
3755  {
3756  $new_node =& $parent_childs[0]->insert_before($new_node, $parent_childs[0]);
3757  }
3758  $a_cont_obj->setNode($new_node);
3759 //echo "PP";
3760  break;
3761  }
3762 
3763  //check for PlaceHolder to remove in EditMode-keep in Layout Mode
3764  if (!$this->getLayoutMode()) {
3765  $sub_nodes = $curr_node->child_nodes() ;
3766  foreach ( $sub_nodes as $sub_node ) {
3767  if ($sub_node->node_name() == "PlaceHolder") {
3768  $curr_node->unlink_node();
3769  }
3770  }
3771  }
3772  }
3773 
3777  function insertContentNode(&$a_cont_node, $a_pos, $a_mode = IL_INSERT_AFTER, $a_pcid = "")
3778  {
3779  // move mode into container elements is always INSERT_CHILD
3780  $curr_node = $this->getContentNode($a_pos, $a_pcid);
3781  $curr_name = $curr_node->node_name();
3782  if (($curr_name == "TableData") || ($curr_name == "PageObject") ||
3783  ($curr_name == "ListItem") || ($curr_name == "Section")
3784  || ($curr_name == "Tab") || ($curr_name == "ContentPopup"))
3785  {
3786  $a_mode = IL_INSERT_CHILD;
3787  }
3788 
3789  $hid = $curr_node->get_attribute("HierId");
3790  if ($hid != "")
3791  {
3792  $a_pos = $hid;
3793  }
3794 
3795  if($a_mode != IL_INSERT_CHILD) // determine parent hierarchical id
3796  { // of sibling at $a_pos
3797  $pos = explode("_", $a_pos);
3798  $target_pos = array_pop($pos);
3799  $parent_pos = implode($pos, "_");
3800  }
3801  else // if we should insert a child, $a_pos is alreade the hierarchical id
3802  { // of the parent node
3803  $parent_pos = $a_pos;
3804  }
3805 
3806  // get the parent node
3807  if($parent_pos != "")
3808  {
3809  $parent_node =& $this->getContentNode($parent_pos);
3810  }
3811  else
3812  {
3813  $parent_node =& $this->getNode();
3814  }
3815 
3816  // count the parent children
3817  $parent_childs =& $parent_node->child_nodes();
3818  $cnt_parent_childs = count($parent_childs);
3819 
3820  switch ($a_mode)
3821  {
3822  // insert new node after sibling at $a_pos
3823  case IL_INSERT_AFTER:
3824  //$new_node =& $a_cont_obj->getNode();
3825  if($succ_node = $curr_node->next_sibling())
3826  {
3827  $a_cont_node = $succ_node->insert_before($a_cont_node, $succ_node);
3828  }
3829  else
3830  {
3831  $a_cont_node = $parent_node->append_child($a_cont_node);
3832  }
3833  //$a_cont_obj->setNode($new_node);
3834  break;
3835 
3836  case IL_INSERT_BEFORE:
3837  //$new_node =& $a_cont_obj->getNode();
3838  $succ_node = $this->getContentNode($a_pos);
3839  $a_cont_node = $succ_node->insert_before($a_cont_node, $succ_node);
3840  //$a_cont_obj->setNode($new_node);
3841  break;
3842 
3843  // insert new node as first child of parent $a_pos (= $a_parent)
3844  case IL_INSERT_CHILD:
3845  //$new_node =& $a_cont_obj->getNode();
3846  if($cnt_parent_childs == 0)
3847  {
3848  $a_cont_node = $parent_node->append_child($a_cont_node);
3849  }
3850  else
3851  {
3852  $a_cont_node = $parent_childs[0]->insert_before($a_cont_node, $parent_childs[0]);
3853  }
3854  //$a_cont_obj->setNode($new_node);
3855  break;
3856  }
3857  }
3858 
3863  function moveContentBefore($a_source, $a_target, $a_spcid = "", $a_tpcid = "")
3864  {
3865  if($a_source == $a_target)
3866  {
3867  return;
3868  }
3869 
3870  // clone the node
3871  $content =& $this->getContentObject($a_source, $a_spcid);
3872  $source_node =& $content->getNode();
3873  $clone_node =& $source_node->clone_node(true);
3874 
3875  // delete source node
3876  $this->deleteContent($a_source, false, $a_spcid);
3877 
3878  // insert cloned node at target
3879  $content->setNode($clone_node);
3880  $this->insertContent($content, $a_target, IL_INSERT_BEFORE, $a_tpcid);
3881  return $this->update();
3882 
3883  }
3884 
3889  function moveContentAfter($a_source, $a_target, $a_spcid = "", $a_tpcid = "")
3890  {
3891  if($a_source == $a_target)
3892  {
3893  return;
3894  }
3895 
3896  // clone the node
3897  $content =& $this->getContentObject($a_source, $a_spcid);
3898  $source_node =& $content->getNode();
3899  $clone_node =& $source_node->clone_node(true);
3900 
3901  // delete source node
3902  $this->deleteContent($a_source, false, $a_spcid);
3903 
3904  // insert cloned node at target
3905  $content->setNode($clone_node);
3906  $this->insertContent($content, $a_target, IL_INSERT_AFTER, $a_tpcid);
3907  return $this->update();
3908  }
3909 
3913  function bbCode2XML(&$a_content)
3914  {
3915  $a_content = eregi_replace("\[com\]","<Comment>",$a_content);
3916  $a_content = eregi_replace("\[\/com\]","</Comment>",$a_content);
3917  $a_content = eregi_replace("\[emp]","<Emph>",$a_content);
3918  $a_content = eregi_replace("\[\/emp\]","</Emph>",$a_content);
3919  $a_content = eregi_replace("\[str]","<Strong>",$a_content);
3920  $a_content = eregi_replace("\[\/str\]","</Strong>",$a_content);
3921  }
3922 
3927  function insertInstIntoIDs($a_inst, $a_res_ref_to_obj_id = true)
3928  {
3929  // insert inst id into internal links
3930  $xpc = xpath_new_context($this->dom);
3931  $path = "//IntLink";
3932  $res =& xpath_eval($xpc, $path);
3933  for($i = 0; $i < count($res->nodeset); $i++)
3934  {
3935  $target = $res->nodeset[$i]->get_attribute("Target");
3936  $type = $res->nodeset[$i]->get_attribute("Type");
3937 
3938  if (substr($target, 0, 4) == "il__")
3939  {
3940  $id = substr($target, 4, strlen($target) - 4);
3941 
3942  // convert repository links obj_<ref_id> to <type>_<obj_id>
3943  // this leads to bug 6685.
3944  if ($a_res_ref_to_obj_id && $type == "RepositoryItem")
3945  {
3946  $id_arr = explode("_", $id);
3947 
3948  // changed due to bug 6685
3949  $ref_id = $id_arr[1];
3950  $obj_id = ilObject::_lookupObjId($id_arr[1]);
3951 
3952  $otype = ilObject::_lookupType($obj_id);
3953  if ($obj_id > 0)
3954  {
3955  // changed due to bug 6685
3956  // the ref_id should be used, if the content is
3957  // imported on the same installation
3958  // the obj_id should be used, if a different
3959  // installation imports, but has an import_id for
3960  // the object id.
3961  $id = $otype."_".$obj_id."_".$ref_id;
3962  //$id = $otype."_".$ref_id;
3963  }
3964  }
3965  $new_target = "il_".$a_inst."_".$id;
3966  $res->nodeset[$i]->set_attribute("Target", $new_target);
3967  }
3968  }
3969  unset($xpc);
3970 
3971  // insert inst id into media aliases
3972  $xpc = xpath_new_context($this->dom);
3973  $path = "//MediaAlias";
3974  $res =& xpath_eval($xpc, $path);
3975  for($i = 0; $i < count($res->nodeset); $i++)
3976  {
3977  $origin_id = $res->nodeset[$i]->get_attribute("OriginId");
3978  if (substr($origin_id, 0, 4) == "il__")
3979  {
3980  $new_id = "il_".$a_inst."_".substr($origin_id, 4, strlen($origin_id) - 4);
3981  $res->nodeset[$i]->set_attribute("OriginId", $new_id);
3982  }
3983  }
3984  unset($xpc);
3985 
3986  // insert inst id file item identifier entries
3987  $xpc = xpath_new_context($this->dom);
3988  $path = "//FileItem/Identifier";
3989  $res =& xpath_eval($xpc, $path);
3990  for($i = 0; $i < count($res->nodeset); $i++)
3991  {
3992  $origin_id = $res->nodeset[$i]->get_attribute("Entry");
3993  if (substr($origin_id, 0, 4) == "il__")
3994  {
3995  $new_id = "il_".$a_inst."_".substr($origin_id, 4, strlen($origin_id) - 4);
3996  $res->nodeset[$i]->set_attribute("Entry", $new_id);
3997  }
3998  }
3999  unset($xpc);
4000 
4001  // insert inst id into question references
4002  $xpc = xpath_new_context($this->dom);
4003  $path = "//Question";
4004  $res =& xpath_eval($xpc, $path);
4005  for($i = 0; $i < count($res->nodeset); $i++)
4006  {
4007  $qref = $res->nodeset[$i]->get_attribute("QRef");
4008 //echo "<br>setted:".$qref;
4009  if (substr($qref, 0, 4) == "il__")
4010  {
4011  $new_id = "il_".$a_inst."_".substr($qref, 4, strlen($qref) - 4);
4012 //echo "<br>setting:".$new_id;
4013  $res->nodeset[$i]->set_attribute("QRef", $new_id);
4014  }
4015  }
4016  unset($xpc);
4017 
4018  }
4019 
4024  function highlightText($a_text, $proglang, $autoindent)
4025  {
4026 
4027  if (!$this->hasHighlighter($proglang)) {
4028  $proglang="plain";
4029  }
4030 
4031  require_once("./Services/COPage/syntax_highlight/php/HFile/HFile_".$proglang.".php");
4032  $classname = "HFile_$proglang";
4033  $h_instance = new $classname();
4034  if ($autoindent == "n") {
4035  $h_instance ->notrim = 1;
4036  $h_instance ->indent = array ("");
4037  $h_instance ->unindent = array ("");
4038  }
4039 
4040  $highlighter = new Core($h_instance, new Output_css());
4041  $a_text = $highlighter->highlight_text(html_entity_decode($a_text));
4042 
4043  return $a_text;
4044  }
4045 
4046  function hasHighlighter ($hfile_ext) {
4047  return file_exists ("Services/COPage/syntax_highlight/php/HFile/HFile_".$hfile_ext.".php");
4048  }
4049 
4055  function insertSourceCodeParagraphs($a_output, $outputmode = "presentation")
4056  {
4057  $xpc = xpath_new_context($this->dom);
4058  $path = "//Paragraph"; //"[@Characteristic = 'Code']";
4059  $res = & xpath_eval($xpc, $path);
4060  for($i = 0; $i < count($res->nodeset); $i++)
4061  {
4062  $context_node = $res->nodeset[$i];
4063  $char = $context_node->get_attribute('Characteristic');
4064 
4065  if ($char != "Code")
4066  continue;
4067 
4068  $n = $context_node->parent_node();
4069  $char = $context_node->get_attribute('Characteristic');
4070  $subchar = $context_node->get_attribute('SubCharacteristic');
4071  $showlinenumbers = $context_node->get_attribute('ShowLineNumbers');
4072  $downloadtitle = $context_node->get_attribute('DownloadTitle');
4073  $autoindent = $context_node->get_attribute('AutoIndent');
4074 
4075  $content = "";
4076 
4077  // get XML Content
4078  $childs = $context_node->child_nodes();
4079 
4080  for($j=0; $j<count($childs); $j++)
4081  {
4082  $content .= $this->dom->dump_node($childs[$j]);
4083  }
4084 
4085  while ($context_node->has_child_nodes ())
4086  {
4087  $node_del = $context_node->first_child ();
4088  $context_node->remove_child ($node_del);
4089  }
4090 
4091  $content = str_replace("<br />", "<br/>", utf8_decode($content) );
4092  $content = str_replace("<br/>", "\n", $content);
4093  $rownums = count(split ("\n",$content));
4094 
4095  $plain_content = html_entity_decode($content);
4096  $plain_content = preg_replace ("/\&#x([1-9a-f]{2});?/ise","chr (base_convert (\\1, 16, 10))",$plain_content);
4097  $plain_content = preg_replace ("/\&#(\d+);?/ise","chr (\\1)",$plain_content);
4098  $content = utf8_encode($this->highlightText($plain_content, $subchar, $autoindent));
4099 
4100  $content = str_replace("&amp;lt;", "&lt;", $content);
4101  $content = str_replace("&amp;gt;", "&gt;", $content);
4102 // $content = str_replace("&", "&amp;", $content);
4103 //var_dump($content);
4104  $rows = "<tr valign=\"top\">";
4105  $rownumbers = "";
4106  $linenumbers= "";
4107 
4108  //if we have to show line numbers
4109  if (strcmp($showlinenumbers,"y")==0)
4110  {
4111  $linenumbers = "<td nowrap=\"nowrap\" class=\"ilc_LineNumbers\" >";
4112  $linenumbers .= "<pre class=\"ilc_Code\">";
4113 
4114  for ($j=0; $j < $rownums; $j++)
4115  {
4116  $indentno = strlen($rownums) - strlen($j+1) + 2;
4117  $rownumeration = ($j+1);
4118  $linenumbers .= "<span class=\"ilc_LineNumber\">$rownumeration</span>";
4119  if ($j < $rownums-1)
4120  {
4121  $linenumbers .= "\n";
4122  }
4123  }
4124  $linenumbers .= "</pre>";
4125  $linenumbers .= "</td>";
4126  }
4127 
4128  $rows .= $linenumbers."<td class=\"ilc_Sourcecode\"><pre class=\"ilc_Code\">".$content."</pre></td>";
4129  $rows .= "</tr>";
4130 
4131  // fix for ie explorer which is not able to produce empty line feeds with <br /><br />;
4132  // workaround: add a space after each br.
4133  $newcontent = str_replace("\n", "<br/>",$rows);
4134  // fix for IE
4135  $newcontent = str_replace("<br/><br/>", "<br/> <br/>",$newcontent);
4136  // falls drei hintereinander...
4137  $newcontent = str_replace("<br/><br/>", "<br/> <br/>",$newcontent);
4138 
4139  // workaround for preventing template engine
4140  // from hiding paragraph text that is enclosed
4141  // in curly brackets (e.g. "{a}", see ilLMEditorGUI::executeCommand())
4142  $newcontent = str_replace("{", "&#123;", $newcontent);
4143  $newcontent = str_replace("}", "&#125;", $newcontent);
4144 
4145 //echo htmlentities($newcontent);
4146  $a_output = str_replace("[[[[[Code;".($i + 1)."]]]]]", $newcontent, $a_output);
4147 
4148  if ($outputmode != "presentation" && is_object($this->offline_handler)
4149  && trim($downloadtitle) != "")
4150  {
4151  // call code handler for offline versions
4152  $this->offline_handler->handleCodeParagraph ($this->id, $i + 1, $downloadtitle, $plain_content);
4153  }
4154  }
4155 
4156  return $a_output;
4157  }
4158 
4159 
4163  function checkPCIds()
4164  {
4165  $this->builddom();
4166  $mydom = $this->dom;
4167 
4168  $sep = $path = "";
4169  foreach ($this->id_elements as $el)
4170  {
4171  $path.= $sep."//".$el."[not(@PCID)]";
4172  $sep = " | ";
4173  }
4174 
4175  $xpc = xpath_new_context($mydom);
4176  $res = & xpath_eval($xpc, $path);
4177 
4178  if (count ($res->nodeset) > 0)
4179  {
4180  return false;
4181  }
4182  return true;
4183  }
4184 
4191  function getAllPCIds()
4192  {
4193  $this->builddom();
4194  $mydom = $this->dom;
4195 
4196  $pcids = array();
4197 
4198  $sep = $path = "";
4199  foreach ($this->id_elements as $el)
4200  {
4201  $path.= $sep."//".$el."[@PCID]";
4202  $sep = " | ";
4203  }
4204 
4205  // get existing ids
4206  $xpc = xpath_new_context($mydom);
4207  $res = & xpath_eval($xpc, $path);
4208 
4209  for ($i = 0; $i < count ($res->nodeset); $i++)
4210  {
4211  $node = $res->nodeset[$i];
4212  $pcids[] = $node->get_attribute("PCID");
4213  }
4214  return $pcids;
4215  }
4216 
4223  function existsPCId($a_pc_id)
4224  {
4225  $this->builddom();
4226  $mydom = $this->dom;
4227 
4228  $pcids = array();
4229 
4230  $sep = $path = "";
4231  foreach ($this->id_elements as $el)
4232  {
4233  $path.= $sep."//".$el."[@PCID='".$a_pc_id."']";
4234  $sep = " | ";
4235  }
4236 
4237  // get existing ids
4238  $xpc = xpath_new_context($mydom);
4239  $res = & xpath_eval($xpc, $path);
4240  return (count($res->nodeset) > 0);
4241  }
4242 
4249  function generatePcId($a_pc_ids = false)
4250  {
4251  if ($a_pc_ids === false)
4252  {
4253  $a_pc_ids = $this->getAllPCIds();
4254  }
4255  $id = ilUtil::randomHash(10, $a_pc_ids);
4256  return $id;
4257  }
4258 
4259 
4263  function insertPCIds()
4264  {
4265  $this->builddom();
4266  $mydom = $this->dom;
4267 
4268  $pcids = $this->getAllPCIds();
4269 
4270  // add missing ones
4271  $sep = $path = "";
4272  foreach ($this->id_elements as $el)
4273  {
4274  $path.= $sep."//".$el."[not(@PCID)]";
4275  $sep = " | ";
4276  }
4277  $xpc = xpath_new_context($mydom);
4278  $res = & xpath_eval($xpc, $path);
4279 
4280  for ($i = 0; $i < count ($res->nodeset); $i++)
4281  {
4282  $node = $res->nodeset[$i];
4283  $id = ilUtil::randomHash(10, $pcids);
4284  $pcids[] = $id;
4285 //echo "setting-".$id."-";
4286  $res->nodeset[$i]->set_attribute("PCID", $id);
4287  }
4288  }
4289 
4294  {
4295  $this->builddom();
4296  $this->addHierIds();
4297  $mydom = $this->dom;
4298 
4299  // get existing ids
4300  $path = "//PageContent";
4301  $xpc = xpath_new_context($mydom);
4302  $res = & xpath_eval($xpc, $path);
4303 
4304  $hashes = array();
4305  require_once("./Services/COPage/classes/class.ilPCParagraph.php");
4306  for ($i = 0; $i < count ($res->nodeset); $i++)
4307  {
4308  $hier_id = $res->nodeset[$i]->get_attribute("HierId");
4309  $pc_id = $res->nodeset[$i]->get_attribute("PCID");
4310  $dump = $mydom->dump_node($res->nodeset[$i]);
4311  if (($hpos = strpos($dump, ' HierId="'.$hier_id.'"')) > 0)
4312  {
4313  $dump = substr($dump, 0, $hpos).
4314  substr($dump, $hpos + strlen(' HierId="'.$hier_id.'"'));
4315  }
4316 
4317  $childs = $res->nodeset[$i]->child_nodes();
4318  $content = "";
4319  if ($childs[0] && $childs[0]->node_name() == "Paragraph")
4320  {
4321  $content = $mydom->dump_node($childs[0]);
4322  $content = substr($content, strpos($content, ">") + 1,
4323  strrpos($content, "<") - (strpos($content, ">") + 1));
4324 //var_dump($content);
4325  $content = ilPCParagraph::xml2output($content);
4326 //var_dump($content);
4327  }
4328  //$hashes[$hier_id] =
4329  // array("PCID" => $pc_id, "hash" => md5($dump));
4330  $hashes[$pc_id] =
4331  array("hier_id" => $hier_id, "hash" => md5($dump), "content" => $content);
4332  }
4333 
4334  return $hashes;
4335  }
4336 
4340  function getQuestionIds()
4341  {
4342  $this->builddom();
4343  $mydom = $this->dom;
4344 
4345  // Get question IDs
4346  $path = "//Question";
4347  $xpc = xpath_new_context($mydom);
4348  $res = & xpath_eval($xpc, $path);
4349 
4350  $q_ids = array();
4351  include_once("./Services/COPage/classes/class.ilInternalLink.php");
4352  for ($i = 0; $i < count ($res->nodeset); $i++)
4353  {
4354  $qref = $res->nodeset[$i]->get_attribute("QRef");
4355 
4356  $inst_id = ilInternalLink::_extractInstOfTarget($qref);
4357  $obj_id = ilInternalLink::_extractObjIdOfTarget($qref);
4358 
4359  if (!($inst_id > 0))
4360  {
4361  if ($obj_id > 0)
4362  {
4363  $q_ids[] = $obj_id;
4364  }
4365  }
4366  }
4367  return $q_ids;
4368  }
4369 
4370  function send_paragraph ($par_id, $filename)
4371  {
4372  $this->builddom();
4373 
4374  $mydom = $this->dom;
4375 
4376  $xpc = xpath_new_context($mydom);
4377 
4378  //$path = "//PageContent[position () = $par_id]/Paragraph";
4379  //$path = "//Paragraph[$par_id]";
4380  $path = "/descendant::Paragraph[position() = $par_id]";
4381 
4382  $res = & xpath_eval($xpc, $path);
4383 
4384  if (count ($res->nodeset) != 1)
4385  die ("Should not happen");
4386 
4387  $context_node = $res->nodeset[0];
4388 
4389  // get plain text
4390 
4391  $childs = $context_node->child_nodes();
4392 
4393  for($j=0; $j<count($childs); $j++)
4394  {
4395  $content .= $mydom->dump_node($childs[$j]);
4396  }
4397 
4398  $content = str_replace("<br />", "\n", $content);
4399  $content = str_replace("<br/>", "\n", $content);
4400 
4401  $plain_content = html_entity_decode($content);
4402 
4403  ilUtil::deliverData($plain_content, $filename);
4404  /*
4405  $file_type = "application/octet-stream";
4406  header("Content-type: ".$file_type);
4407  header("Content-disposition: attachment; filename=\"$filename\"");
4408  echo $plain_content;*/
4409  exit();
4410  }
4411 
4415  function getFO()
4416  {
4417  $xml = $this->getXMLFromDom(false, true, true);
4418  $xsl = file_get_contents("./Services/COPage/xsl/page_fo.xsl");
4419  $args = array( '/_xml' => $xml, '/_xsl' => $xsl );
4420  $xh = xslt_create();
4421 
4422  $params = array ();
4423 
4424 
4425  $fo = xslt_process($xh,"arg:/_xml","arg:/_xsl",NULL,$args, $params);
4426  var_dump($fo);
4427  // do some replacements
4428  $fo = str_replace("\n", "", $fo);
4429  $fo = str_replace("<br/>", "<br>", $fo);
4430  $fo = str_replace("<br>", "\n", $fo);
4431 
4432  xslt_free($xh);
4433 
4434  //
4435  $fo = substr($fo, strpos($fo,">") + 1);
4436 //echo "<br><b>fo:</b><br>".htmlentities($fo); flush();
4437  return $fo;
4438  }
4439 
4440  function registerOfflineHandler ($handler) {
4441  $this->offline_handler = $handler;
4442  }
4443 
4447  function _lookupContainsDeactivatedElements($a_id, $a_parent_type)
4448  {
4449  global $ilDB;
4450 
4451  /*$query = "SELECT * FROM page_object WHERE page_id = ".
4452  $ilDB->quote($a_id)." AND ".
4453  " parent_type = ".$ilDB->quote($a_parent_type)." AND ".
4454  " content LIKE '% Enabled=\"False\"%'";*/
4455  $query = "SELECT * FROM page_object WHERE page_id = ".
4456  $ilDB->quote($a_id, "integer")." AND ".
4457  " parent_type = ".$ilDB->quote($a_parent_type, "text")." AND ".
4458  " inactive_elements = ".$ilDB->quote(1, "integer");
4459  $obj_set = $ilDB->query($query);
4460 
4461  if ($obj_rec = $obj_set->fetchRow(DB_FETCHMODE_ASSOC))
4462  {
4463  return true;
4464  }
4465 
4466  return false;
4467  }
4468 
4475  function containsDeactivatedElements($a_content)
4476  {
4477  if (strpos($a_content, " Enabled=\"False\""))
4478  {
4479  return true;
4480  }
4481  return false;
4482  }
4483 
4488  {
4489  global $ilDB;
4490 
4491  $h_query = "SELECT * FROM page_history ".
4492  " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
4493  " AND parent_type = ".$ilDB->quote($this->getParentType(), "text").
4494  " ORDER BY hdate DESC";
4495 
4496  $hset = $ilDB->query($h_query);
4497  $hentries = array();
4498 
4499  while ($hrec = $ilDB->fetchAssoc($hset))
4500  {
4501  $hrec["sortkey"] = (int) $hrec["nr"];
4502  $hrec["user"] = (int) $hrec["user_id"];
4503  $hentries[] = $hrec;
4504  }
4505 //var_dump($hentries);
4506  return $hentries;
4507  }
4508 
4512  function getHistoryEntry($a_old_nr)
4513  {
4514  global $ilDB;
4515 
4516  $res = $ilDB->queryF("SELECT * FROM page_history ".
4517  " WHERE page_id = %s ".
4518  " AND parent_type = %s ".
4519  " AND nr = %s",
4520  array("integer", "text", "integer"),
4521  array($this->getId(), $this->getParentType(), $a_old_nr));
4522  if ($hrec = $ilDB->fetchAssoc($res))
4523  {
4524  return $hrec;
4525  }
4526 
4527  return false;
4528  }
4529 
4530 
4537  function getHistoryInfo($a_nr)
4538  {
4539  global $ilDB;
4540 
4541  // determine previous entry
4542  $res = $ilDB->query("SELECT MAX(nr) mnr FROM page_history ".
4543  " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
4544  " AND parent_type = ".$ilDB->quote($this->getParentType(), "text").
4545  " AND nr < ".$ilDB->quote((int) $a_nr, "integer"));
4546  $row = $ilDB->fetchAssoc($res);
4547  if ($row["mnr"] > 0)
4548  {
4549  $res = $ilDB->query("SELECT * FROM page_history ".
4550  " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
4551  " AND parent_type = ".$ilDB->quote($this->getParentType(), "text").
4552  " AND nr = ".$ilDB->quote((int) $row["mnr"], "integer"));
4553  $row = $ilDB->fetchAssoc($res);
4554  $ret["previous"] = $row;
4555  }
4556 
4557  // determine next entry
4558  $res = $ilDB->query("SELECT MIN(nr) mnr FROM page_history ".
4559  " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
4560  " AND parent_type = ".$ilDB->quote($this->getParentType(), "text").
4561  " AND nr > ".$ilDB->quote((int) $a_nr, "integer"));
4562  $row = $ilDB->fetchAssoc($res);
4563  if ($row["mnr"] > 0)
4564  {
4565  $res = $ilDB->query("SELECT * FROM page_history ".
4566  " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
4567  " AND parent_type = ".$ilDB->quote($this->getParentType(), "text").
4568  " AND nr = ".$ilDB->quote((int) $row["mnr"], "integer"));
4569  $row = $ilDB->fetchAssoc($res);
4570  $ret["next"] = $row;
4571  }
4572 
4573  // current
4574  $res = $ilDB->query("SELECT * FROM page_history ".
4575  " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
4576  " AND parent_type = ".$ilDB->quote($this->getParentType(), "text").
4577  " AND nr = ".$ilDB->quote((int) $a_nr, "integer"));
4578  $row = $ilDB->fetchAssoc($res);
4579  $ret["current"] = $row;
4580 
4581  return $ret;
4582  }
4583 
4584  function addChangeDivClasses($a_hashes)
4585  {
4586  $xpc = xpath_new_context($this->dom);
4587  $path = "/*[1]";
4588  $res =& xpath_eval($xpc, $path);
4589  $rnode = $res->nodeset[0];
4590 
4591 //echo "A";
4592  foreach($a_hashes as $pc_id => $h)
4593  {
4594 //echo "B";
4595  if ($h["change"] != "")
4596  {
4597 //echo "<br>C-".$h["hier_id"]."-".$h["change"]."-";
4598  $dc_node = $this->dom->create_element("DivClass");
4599  $dc_node->set_attribute("HierId", $h["hier_id"]);
4600  $dc_node->set_attribute("Class", "ilEdit".$h["change"]);
4601  $dc_node = $rnode->append_child($dc_node);
4602  }
4603  }
4604  }
4605 
4612  function compareVersion($a_left, $a_right)
4613  {
4614  global $ilDB;
4615 
4616  // get page objects
4617  $l_page = new ilPageObject($this->getParentType(), $this->getId(), $a_left);
4618  $r_page = new ilPageObject($this->getParentType(), $this->getId(), $a_right);
4619 
4620  $l_hashes = $l_page->getPageContentsHashes();
4621  $r_hashes = $r_page->getPageContentsHashes();
4622 
4623  // determine all deleted and changed page elements
4624  foreach ($l_hashes as $pc_id => $h)
4625  {
4626  if (!isset($r_hashes[$pc_id]))
4627  {
4628  $l_hashes[$pc_id]["change"] = "Deleted";
4629  }
4630  else
4631  {
4632  if ($l_hashes[$pc_id]["hash"] != $r_hashes[$pc_id]["hash"])
4633  {
4634  $l_hashes[$pc_id]["change"] = "Modified";
4635  $r_hashes[$pc_id]["change"] = "Modified";
4636 
4637  include_once("./Services/COPage/mediawikidiff/class.WordLevelDiff.php");
4638  // if modified element is a paragraph, highlight changes
4639  if ($l_hashes[$pc_id]["content"] != "" &&
4640  $r_hashes[$pc_id]["content"] != "")
4641  {
4642  $new_left = str_replace("\n", "<br />", $l_hashes[$pc_id]["content"]);
4643  $new_right = str_replace("\n", "<br />", $r_hashes[$pc_id]["content"]);
4644  $wldiff = new WordLevelDiff(array($new_left),
4645  array($new_right));
4646  $new_left = $wldiff->orig();
4647  $new_right = $wldiff->closing();
4648  $l_page->setParagraphContent($l_hashes[$pc_id]["hier_id"], $new_left[0]);
4649  $r_page->setParagraphContent($l_hashes[$pc_id]["hier_id"], $new_right[0]);
4650  }
4651  }
4652  }
4653  }
4654 
4655  // determine all new paragraphs
4656  foreach ($r_hashes as $pc_id => $h)
4657  {
4658  if (!isset($l_hashes[$pc_id]))
4659  {
4660  $r_hashes[$pc_id]["change"] = "New";
4661  }
4662  }
4663 
4664  $l_page->addChangeDivClasses($l_hashes);
4665  $r_page->addChangeDivClasses($r_hashes);
4666 
4667  return array("l_page" => $l_page, "r_page" => $r_page,
4668  "l_changes" => $l_hashes, "r_changes" => $r_hashes);
4669  }
4670 
4674  function increaseViewCnt()
4675  {
4676  global $ilDB;
4677 
4678  $ilDB->manipulate("UPDATE page_object ".
4679  " SET view_cnt = view_cnt + 1 ".
4680  " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
4681  " AND parent_type = ".$ilDB->quote($this->getParentType(), "text"));
4682  //$ilDB->query($q);
4683  }
4684 
4692  static function getRecentChanges($a_parent_type, $a_parent_id, $a_period = 30)
4693  {
4694  global $ilDB;
4695 
4696  $page_changes = array();
4697  $limit_ts = date('Y-m-d H:i:s', time() - ($a_period * 24 * 60 * 60));
4698  $q = "SELECT * FROM page_object ".
4699  " WHERE parent_id = ".$ilDB->quote($a_parent_id, "integer").
4700  " AND parent_type = ".$ilDB->quote($a_parent_type, "text").
4701  " AND last_change >= ".$ilDB->quote($limit_ts, "timestamp");
4702  // " AND (TO_DAYS(now()) - TO_DAYS(last_change)) <= ".((int)$a_period);
4703  $set = $ilDB->query($q);
4704  while($page = $ilDB->fetchAssoc($set))
4705  {
4706  $page_changes[] = array("date" => $page["last_change"],
4707  "id" => $page["page_id"], "type" => "page",
4708  "user" => $page["last_change_user"]);
4709  }
4710 
4711  $and_str = "";
4712  if ($a_period > 0)
4713  {
4714  $limit_ts = date('Y-m-d H:i:s', time() - ($a_period * 24 * 60 * 60));
4715  $and_str = " AND hdate >= ".$ilDB->quote($limit_ts, "timestamp")." ";
4716  }
4717 
4718  $q = "SELECT * FROM page_history ".
4719  " WHERE parent_id = ".$ilDB->quote($a_parent_id, "integer").
4720  " AND parent_type = ".$ilDB->quote($a_parent_type, "text").
4721  $and_str;
4722  $set = $ilDB->query($q);
4723  while ($page = $ilDB->fetchAssoc($set))
4724  {
4725  $page_changes[] = array("date" => $page["hdate"],
4726  "id" => $page["page_id"], "type" => "hist", "nr" => $page["nr"],
4727  "user" => $page["user_id"]);
4728  }
4729 
4730  $page_changes = ilUtil::sortArray($page_changes, "date", "desc");
4731 
4732  return $page_changes;
4733  }
4734 
4742  static function getAllPages($a_parent_type, $a_parent_id)
4743  {
4744  global $ilDB;
4745 
4746  $page_changes = array();
4747 
4748  $q = "SELECT * FROM page_object ".
4749  " WHERE parent_id = ".$ilDB->quote($a_parent_id, "integer").
4750  " AND parent_type = ".$ilDB->quote($a_parent_type, "text");
4751  $set = $ilDB->query($q);
4752  $pages = array();
4753  while ($page = $ilDB->fetchAssoc($set))
4754  {
4755  $pages[$page["page_id"]] = array("date" => $page["last_change"],
4756  "id" => $page["page_id"], "user" => $page["last_change_user"]);
4757  }
4758 
4759  return $pages;
4760  }
4761 
4768  static function getNewPages($a_parent_type, $a_parent_id)
4769  {
4770  global $ilDB;
4771 
4772  $pages = array();
4773 
4774  $q = "SELECT * FROM page_object ".
4775  " WHERE parent_id = ".$ilDB->quote($a_parent_id, "integer").
4776  " AND parent_type = ".$ilDB->quote($a_parent_type, "text").
4777  " ORDER BY created DESC";
4778  $set = $ilDB->query($q);
4779  while($page = $ilDB->fetchAssoc($set))
4780  {
4781  if ($page["created"] != "")
4782  {
4783  $pages[] = array("created" => $page["created"],
4784  "id" => $page["page_id"],
4785  "user" => $page["create_user"],
4786  );
4787  }
4788  }
4789 
4790  return $pages;
4791  }
4792 
4799  static function getParentObjectContributors($a_parent_type, $a_parent_id)
4800  {
4801  global $ilDB;
4802 
4803  $contributors = array();
4804  $set = $ilDB->queryF("SELECT last_change_user FROM page_object ".
4805  " WHERE parent_id = %s AND parent_type = %s ".
4806  " AND last_change_user != %s",
4807  array("integer", "text", "integer"),
4808  array($a_parent_id, $a_parent_type, 0));
4809 
4810  while ($page = $ilDB->fetchAssoc($set))
4811  {
4812  $contributors[$page["last_change_user"]][$page["page_id"]] = 1;
4813  }
4814 
4815  $set = $ilDB->queryF("SELECT count(DISTINCT page_id, parent_type, hdate) as cnt, page_id, user_id FROM page_history ".
4816  " WHERE parent_id = %s AND parent_type = %s AND user_id != %s ".
4817  " GROUP BY page_id, user_id ",
4818  array("integer", "text", "integer"),
4819  array($a_parent_id, $a_parent_type, 0));
4820  while ($hpage = $ilDB->fetchAssoc($set))
4821  {
4822  $contributors[$hpage["user_id"]][$hpage["page_id"]] =
4823  $contributors[$hpage["user_id"]][$hpage["page_id"]] + $hpage["cnt"];
4824  }
4825 
4826  $c = array();
4827  foreach ($contributors as $k => $co)
4828  {
4829  if (ilObject::_lookupType($k) == "usr")
4830  {
4831  $name = ilObjUser::_lookupName($k);
4832  $c[] = array("user_id" => $k, "pages" => $co,
4833  "lastname" => $name["lastname"], "firstname" => $name["firstname"]);
4834  }
4835  }
4836 
4837  return $c;
4838  }
4839 
4846  static function getPageContributors($a_parent_type, $a_page_id)
4847  {
4848  global $ilDB;
4849 
4850  $contributors = array();
4851  $set = $ilDB->queryF("SELECT last_change_user FROM page_object ".
4852  " WHERE page_id = %s AND parent_type = %s ".
4853  " AND last_change_user != %s",
4854  array("integer", "text", "integer"),
4855  array($a_page_id, $a_parent_type, 0));
4856 
4857  while ($page = $ilDB->fetchAssoc($set))
4858  {
4859  $contributors[$page["last_change_user"]] = 1;
4860  }
4861 
4862  $set = $ilDB->queryF("SELECT count(*) as cnt, page_id, user_id FROM page_history ".
4863  " WHERE page_id = %s AND parent_type = %s AND user_id != %s ".
4864  " GROUP BY user_id, page_id ",
4865  array("integer", "text", "integer"),
4866  array($a_page_id, $a_parent_type, 0));
4867  while ($hpage = $ilDB->fetchAssoc($set))
4868  {
4869  $contributors[$hpage["user_id"]] =
4870  $contributors[$hpage["user_id"]] + $hpage["cnt"];
4871  }
4872 
4873  $c = array();
4874  foreach ($contributors as $k => $co)
4875  {
4876  $name = ilObjUser::_lookupName($k);
4877  $c[] = array("user_id" => $k, "pages" => $co,
4878  "lastname" => $name["lastname"], "firstname" => $name["firstname"]);
4879  }
4880 
4881  return $c;
4882  }
4883 
4887  function writeRenderedContent($a_content, $a_md5)
4888  {
4889  global $ilDB;
4890 
4891  $ilDB->update("page_object", array(
4892  "rendered_content" => array("clob", $a_content),
4893  "render_md5" => array("text", $a_md5),
4894  "rendered_time" => array("timestamp", ilUtil::now())
4895  ), array(
4896  "page_id" => array("integer", $this->getId()),
4897  "parent_type" => array("text", $this->getParentType())
4898  ));
4899  /*$st = $ilDB->prepareManip("UPDATE page_object ".
4900  " SET rendered_content = ?, render_md5 = ?, rendered_time = now()".
4901  " WHERE page_id = ? AND parent_type = ?",
4902  array("text", "text", "integer", "text"));
4903  $r = $ilDB->execute($st,
4904  array($a_content, $a_md5, $this->getId(), $this->getParentType()));*/
4905  }
4906 
4914  static function getPagesWithLinks($a_parent_type, $a_parent_id)
4915  {
4916  global $ilDB;
4917 
4918  $page_changes = array();
4919 
4920  $q = "SELECT * FROM page_object ".
4921  " WHERE parent_id = ".$ilDB->quote($a_parent_id, "integer").
4922  " AND parent_type = ".$ilDB->quote($a_parent_type, "text").
4923  " AND int_links = ".$ilDB->quote(1, "integer");
4924  $set = $ilDB->query($q);
4925  $pages = array();
4926  while ($page = $ilDB->fetchAssoc($set))
4927  {
4928  $pages[$page["page_id"]] = array("date" => $page["last_change"],
4929  "id" => $page["page_id"], "user" => $page["last_change_user"]);
4930  }
4931 
4932  return $pages;
4933  }
4934 
4941  function containsIntLinks($a_content)
4942  {
4943  if (strpos($a_content, "IntLink"))
4944  {
4945  return true;
4946  }
4947  return false;
4948  }
4949 
4954  {
4955  }
4956 
4962  function saveInitialOpenedContent($a_type, $a_id, $a_target)
4963  {
4964  $this->buildDom();
4965 
4966  switch($a_type)
4967  {
4968  case "media":
4969  $link_type = "MediaObject";
4970  $a_id = "il__mob_".$a_id;
4971  break;
4972 
4973  case "page":
4974  $link_type = "PageObject";
4975  $a_id = "il__pg_".$a_id;
4976  break;
4977 
4978  case "term":
4979  $link_type = "GlossaryItem";
4980  $a_id = "il__git_".$a_id;
4981  $a_target = "Glossary";
4982  break;
4983  }
4984 
4985  // if type or id missing -> delete InitOpenedContent, if existing
4986  if ($link_type == "" || $a_id == "")
4987  {
4988  $xpc = xpath_new_context($this->dom);
4989  $path = "//PageObject/InitOpenedContent";
4990  $res = xpath_eval($xpc, $path);
4991  if (count($res->nodeset) > 0)
4992  {
4993  $res->nodeset[0]->unlink_node($res->nodeset[0]);
4994  }
4995  }
4996  else
4997  {
4998  $xpc = xpath_new_context($this->dom);
4999  $path = "//PageObject/InitOpenedContent";
5000  $res = xpath_eval($xpc, $path);
5001  if (count($res->nodeset) > 0)
5002  {
5003  $init_node = $res->nodeset[0];
5004  $childs = $init_node->child_nodes();
5005  for($i = 0; $i < count($childs); $i++)
5006  {
5007  if ($childs[$i]->node_name() == "IntLink")
5008  {
5009  $il_node = $childs[$i];
5010  }
5011  }
5012  }
5013  else
5014  {
5015  $path = "//PageObject";
5016  $res = xpath_eval($xpc, $path);
5017  $page_node = $res->nodeset[0];
5018  $init_node = $this->dom->create_element("InitOpenedContent");
5019  $init_node = $page_node->append_child($init_node);
5020  $il_node = $this->dom->create_element("IntLink");
5021  $il_node = $init_node->append_child($il_node);
5022  }
5023  $il_node->set_attribute("Target", $a_id);
5024  $il_node->set_attribute("Type", $link_type);
5025  $il_node->set_attribute("TargetFrame", $a_target);
5026  }
5027 
5028  $ret = $this->update();
5029  }
5030 
5031 
5038  {
5039  $this->buildDom();
5040 
5041  $xpc = xpath_new_context($this->dom);
5042  $path = "//PageObject/InitOpenedContent";
5043  $res = xpath_eval($xpc, $path);
5044  $il_node = null;
5045  if (count($res->nodeset) > 0)
5046  {
5047  $init_node = $res->nodeset[0];
5048  $childs = $init_node->child_nodes();
5049  for($i = 0; $i < count($childs); $i++)
5050  {
5051  if ($childs[$i]->node_name() == "IntLink")
5052  {
5053  $il_node = $childs[$i];
5054  }
5055  }
5056  }
5057  if (!is_null($il_node))
5058  {
5059  $id = $il_node->get_attribute("Target");
5060  $link_type = $il_node->get_attribute("Type");
5061  $target = $il_node->get_attribute("TargetFrame");
5062 
5063  switch($link_type)
5064  {
5065  case "MediaObject":
5066  $type = "media";
5067  break;
5068 
5069  case "PageObject":
5070  $type = "page";
5071  break;
5072 
5073  case "GlossaryItem":
5074  $type = "term";
5075  break;
5076  }
5077  include_once("./Services/COPage/classes/class.ilInternalLink.php");
5079  return array("id" => $id, "type" => $type, "target" => $target);
5080  }
5081 
5082  return array();
5083  }
5084 
5085 }
5086 ?>