ILIAS  Release_4_0_x_branch Revision 61816
 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_3_11.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");
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 
190 
194  function read()
195  {
196  global $ilBench, $ilDB;
197 
198  $ilBench->start("ContentPresentation", "ilPageObject_read");
199 
200  $this->setActive(true);
201  if ($this->old_nr == 0)
202  {
203  $query = "SELECT * FROM page_object WHERE page_id = ".$ilDB->quote($this->id, "integer")." ".
204  "AND parent_type=".$ilDB->quote($this->getParentType(), "text");
205  $pg_set = $this->ilias->db->query($query);
206  $this->page_record = $ilDB->fetchAssoc($pg_set);
207  $this->setActive($this->page_record["active"]);
208  $this->setActivationStart($this->page_record["activation_start"]);
209  $this->setActivationEnd($this->page_record["activation_end"]);
210  }
211  else
212  {
213  $query = "SELECT * FROM page_history WHERE ".
214  "page_id = ".$ilDB->quote($this->id, "integer")." ".
215  "AND parent_type=".$ilDB->quote($this->getParentType(), "text").
216  " AND nr = ".$ilDB->quote((int) $this->old_nr, "integer");
217  $pg_set = $ilDB->query($query);
218  $this->page_record = $ilDB->fetchAssoc($pg_set);
219  }
220  if (!$this->page_record)
221  {
222  if ($this->halt_on_error)
223  {
224  echo "Error: Page ".$this->id." is not in database".
225  " (parent type ".$this->getParentType().")."; exit;
226  }
227  else
228  {
229  $this->page_not_found = true;
230  return;
231  }
232  }
233  $this->xml = $this->page_record["content"];
234  $this->setParentId($this->page_record["parent_id"]);
235  $this->last_change_user = $this->page_record["last_change_user"];
236  $this->create_user = $this->page_record["create_user"];
237  $this->setRenderedContent($this->page_record["rendered_content"]);
238  $this->setRenderMd5($this->page_record["render_md5"]);
239  $this->setRenderedTime($this->page_record["rendered_time"]);
240  $this->setLastChange($this->page_record["last_change"]);
241 
242  $ilBench->stop("ContentPresentation", "ilPageObject_read");
243  }
244 
251  static function _exists($a_parent_type, $a_id)
252  {
253  global $ilDB;
254 //echo "<br>".$a_parent_type."-".$a_id;
255  if (isset(self::$exists[$a_parent_type.":".$a_id]))
256  {
257 //echo "***HIT";
258  return self::$exists[$a_parent_type.":".$a_id];
259  }
260 
261  $query = "SELECT page_id FROM page_object WHERE page_id = ".$ilDB->quote($a_id, "integer")." ".
262  "AND parent_type= ".$ilDB->quote($a_parent_type, "text");
263 
264  $set = $ilDB->query($query);
265  if ($row = $ilDB->fetchAssoc($set))
266  {
267  self::$exists[$a_parent_type.":".$a_id] = true;
268  return true;
269  }
270  else
271  {
272  self::$exists[$a_parent_type.":".$a_id] = false;
273  return false;
274  }
275  }
276 
283  function _existsAndNotEmpty($a_parent_type, $a_id)
284  {
285  global $ilDB;
286 
287  $query = "SELECT page_id, is_empty FROM page_object WHERE page_id = ".$ilDB->quote($a_id, "integer")." ".
288  "AND parent_type= ".$ilDB->quote($a_parent_type, "text");
289 
290  $set = $ilDB->query($query);
291  if ($row = $ilDB->fetchAssoc($set))
292  {
293  if ($row["is_empty"] != 1)
294  {
295  return true;
296  }
297  }
298  return false;
299  }
300 
301  function buildDom($a_force = false)
302  {
303  global $ilBench;
304 
305  if ($this->dom_builded && !$a_force)
306  {
307  return;
308  }
309 
310 //echo "\n<br>buildDomWith:".$this->getId().":xml:".$this->getXMLContent(true).":<br>";
311 
312  $ilBench->start("ContentPresentation", "ilPageObject_buildDom");
313  $this->dom = @domxml_open_mem($this->getXMLContent(true), DOMXML_LOAD_VALIDATING, $error);
314  $ilBench->stop("ContentPresentation", "ilPageObject_buildDom");
315 
316  $xpc = xpath_new_context($this->dom);
317  $path = "//PageObject";
318  $res =& xpath_eval($xpc, $path);
319  if (count($res->nodeset) == 1)
320  {
321  $this->node =& $res->nodeset[0];
322  }
323 
324  if (empty($error))
325  {
326  $this->dom_builded = true;
327  return true;
328  }
329  else
330  {
331  return $error;
332  }
333  }
334 
335  function freeDom()
336  {
337  //$this->dom->free();
338  unset($this->dom);
339  }
340 
341  function &getDom()
342  {
343  return $this->dom;
344  }
345 
349  function setId($a_id)
350  {
351  $this->id = $a_id;
352  }
353 
354  function getId()
355  {
356  return $this->id;
357  }
358 
359  function setParentId($a_id)
360  {
361  $this->parent_id = $a_id;
362  }
363 
364  function getParentId()
365  {
366  return $this->parent_id;
367  }
368 
369  function setParentType($a_type)
370  {
371  $this->parent_type = $a_type;
372  }
373 
374  function getParentType()
375  {
376  return $this->parent_type;
377  }
378 
379  function addUpdateListener(&$a_object, $a_method, $a_parameters = "")
380  {
382  $this->update_listeners[$cnt]["object"] =& $a_object;
383  $this->update_listeners[$cnt]["method"] = $a_method;
384  $this->update_listeners[$cnt]["parameters"] = $a_parameters;
385  $this->update_listener_cnt++;
386  }
387 
389  {
390  for($i=0; $i<$this->update_listener_cnt; $i++)
391  {
392  $object =& $this->update_listeners[$i]["object"];
393  $method = $this->update_listeners[$i]["method"];
394  $parameters = $this->update_listeners[$i]["parameters"];
395  $object->$method($parameters);
396  }
397  }
398 
404  function setActive($a_active)
405  {
406  $this->active = $a_active;
407  }
408 
414  function getActive($a_check_scheduled_activation = false)
415  {
416  if ($a_check_scheduled_activation && !$this->active)
417  {
418  include_once("./Services/Calendar/classes/class.ilDateTime.php");
420  $end = new ilDateTime($this->getActivationEnd(), IL_CAL_DATETIME);
421  $now = new ilDateTime(time(), IL_CAL_UNIX);
422  if (!ilDateTime::_before($now, $start) && !ilDateTime::_after($now, $end))
423  {
424  return true;
425  }
426  }
427  return $this->active;
428  }
429 
433  function _lookupActive($a_id, $a_parent_type, $a_check_scheduled_activation = false)
434  {
435  global $ilDB;
436 
437  $set = $ilDB->queryF("SELECT active, activation_start, activation_end FROM page_object WHERE page_id = %s".
438  " AND parent_type = %s",
439  array("integer", "text"),
440  array($a_id, $a_parent_type));
441  $rec = $ilDB->fetchAssoc($set);
442  $rec["n"] = ilUtil::now();
443 
444  if (!$rec["active"] && $a_check_scheduled_activation)
445  {
446  if ($rec["n"] >= $rec["activation_start"] &&
447  $rec["n"] <= $rec["activation_end"])
448  {
449  return true;
450  }
451  }
452 
453  return $rec["active"];
454  }
455 
459  static function _isScheduledActivation($a_id, $a_parent_type)
460  {
461  global $ilDB;
462 
463  $set = $ilDB->queryF("SELECT active, activation_start, activation_end FROM page_object WHERE page_id = %s".
464  " AND parent_type = %s", array("integer", "text"),
465  array($a_id, $a_parent_type));
466  $rec = $ilDB->fetchAssoc($set);
467 
468  if (!$rec["active"] && $rec["activation_start"] != "")
469  {
470  return true;
471  }
472 
473  return false;
474  }
475 
479  function _writeActive($a_id, $a_parent_type, $a_active, $a_reset_scheduled_activation = true)
480  {
481  global $ilDB;
482 
483  if ($a_reset_scheduled_activation)
484  {
485  $st = $ilDB->manipulateF("UPDATE page_object SET active = %s, activation_start = %s, ".
486  " activation_end = %s WHERE page_id = %s".
487  " AND parent_type = %s", array("boolean", "timestamp", "timestamp", "integer", "text"),
488  array($a_active, null, null, $a_id, $a_parent_type));
489  }
490  else
491  {
492  $st = $ilDB->prepareManip("UPDATE page_object SET active = %s WHERE page_id = %s".
493  " AND parent_type = %s", array("boolean", "integer", "text"),
494  array($a_active, $a_id, $a_parent_type));
495  }
496  }
497 
501  static function lookupParentId($a_id, $a_type)
502  {
503  global $ilDB;
504 
505  $res = $ilDB->query("SELECT parent_id FROM page_object WHERE page_id = ".$ilDB->quote($a_id, "integer")." ".
506  "AND parent_type=".$ilDB->quote($a_type, "text"));
507  $rec = $ilDB->fetchAssoc($res);
508  return $rec["parent_id"];
509  }
510 
511 
517  function setActivationStart($a_activationstart)
518  {
519  $this->activationstart = $a_activationstart;
520  }
521 
528  {
529  return $this->activationstart;
530  }
531 
537  function setActivationEnd($a_activationend)
538  {
539  $this->activationend = $a_activationend;
540  }
541 
547  function getActivationEnd()
548  {
549  return $this->activationend;
550  }
551 
552  function &getContentObject($a_hier_id, $a_pc_id = "")
553  {
554 //echo ":".$a_hier_id.":";
555 //echo "Content:".htmlentities($this->getXMLFromDOM()).":<br>";
556 //echo "ilPageObject::getContentObject:hierid:".$a_hier_id.":<br>";
557  $cont_node =& $this->getContentNode($a_hier_id, $a_pc_id);
558 //echo "ilPageObject::getContentObject:nodename:".$cont_node->node_name().":<br>";
559  if (!is_object($cont_node))
560  {
561  return false;
562  }
563  switch($cont_node->node_name())
564  {
565  case "PageContent":
566  $child_node =& $cont_node->first_child();
567 //echo "<br>nodename:".$child_node->node_name();
568  switch($child_node->node_name())
569  {
570  case "Paragraph":
571  require_once("./Services/COPage/classes/class.ilPCParagraph.php");
572  $par =& new ilPCParagraph($this->dom);
573  $par->setNode($cont_node);
574  $par->setHierId($a_hier_id);
575  $par->setPcId($a_pc_id);
576  return $par;
577 
578  case "Table":
579  if ($child_node->get_attribute("DataTable") == "y")
580  {
581  require_once("./Services/COPage/classes/class.ilPCDataTable.php");
582  $tab =& new ilPCDataTable($this->dom);
583  $tab->setNode($cont_node);
584  $tab->setHierId($a_hier_id);
585  }
586  else
587  {
588  require_once("./Services/COPage/classes/class.ilPCTable.php");
589  $tab =& new ilPCTable($this->dom);
590  $tab->setNode($cont_node);
591  $tab->setHierId($a_hier_id);
592  }
593  $tab->setPcId($a_pc_id);
594  return $tab;
595 
596  case "MediaObject":
597 if ($_GET["pgEdMediaMode"] != "") {echo "ilPageObject::error media"; exit;}
598 
599  //require_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
600  require_once("./Services/COPage/classes/class.ilPCMediaObject.php");
601 
602  $mal_node =& $child_node->first_child();
603 //echo "ilPageObject::getContentObject:nodename:".$mal_node->node_name().":<br>";
604  $id_arr = explode("_", $mal_node->get_attribute("OriginId"));
605  $mob_id = $id_arr[count($id_arr) - 1];
606 
607  // allow deletion of non-existing media objects
608  if (!ilObject::_exists($mob_id) && in_array("delete", $_POST))
609  {
610  $mob_id = 0;
611  }
612 
613  //$mob =& new ilObjMediaObject($mob_id);
614  $mob = new ilPCMediaObject($this->dom);
615  $mob->readMediaObject($mob_id);
616 
617  //$mob->setDom($this->dom);
618  $mob->setNode($cont_node);
619  $mob->setHierId($a_hier_id);
620  $mob->setPcId($a_pc_id);
621  return $mob;
622 
623  case "List":
624  require_once("./Services/COPage/classes/class.ilPCList.php");
625  $list = new ilPCList($this->dom);
626  $list->setNode($cont_node);
627  $list->setHierId($a_hier_id);
628  $list->setPcId($a_pc_id);
629  return $list;
630 
631  case "FileList":
632  require_once("./Services/COPage/classes/class.ilPCFileList.php");
633  $file_list = new ilPCFileList($this->dom);
634  $file_list->setNode($cont_node);
635  $file_list->setHierId($a_hier_id);
636  $file_list->setPcId($a_pc_id);
637  return $file_list;
638 
639  // note: assessment handling is forwarded to assessment gui classes
640  case "Question":
641  require_once("./Services/COPage/classes/class.ilPCQuestion.php");
642  $pc_question = new ilPCQuestion($this->dom);
643  $pc_question->setNode($cont_node);
644  $pc_question->setHierId($a_hier_id);
645  $pc_question->setPcId($a_pc_id);
646  return $pc_question;
647 
648  case "Section":
649  require_once("./Services/COPage/classes/class.ilPCSection.php");
650  $sec = new ilPCSection($this->dom);
651  $sec->setNode($cont_node);
652  $sec->setHierId($a_hier_id);
653  $sec->setPcId($a_pc_id);
654  return $sec;
655 
656  case "Resources":
657  require_once("./Services/COPage/classes/class.ilPCResources.php");
658  $res = new ilPCResources($this->dom);
659  $res->setNode($cont_node);
660  $res->setHierId($a_hier_id);
661  $res->setPcId($a_pc_id);
662  return $res;
663 
664  case "Map":
665  require_once("./Services/COPage/classes/class.ilPCMap.php");
666  $map = new ilPCMap($this->dom);
667  $map->setNode($cont_node);
668  $map->setHierId($a_hier_id);
669  $map->setPcId($a_pc_id);
670  return $map;
671 
672  case "Tabs":
673  require_once("./Services/COPage/classes/class.ilPCTabs.php");
674  $map = new ilPCTabs($this->dom);
675  $map->setNode($cont_node);
676  $map->setHierId($a_hier_id);
677  $map->setPcId($a_pc_id);
678  return $map;
679 
680  case "Plugged":
681  require_once("./Services/COPage/classes/class.ilPCPlugged.php");
682  $plugged = new ilPCPlugged($this->dom);
683  $plugged->setNode($cont_node);
684  $plugged->setHierId($a_hier_id);
685  $plugged->setPcId($a_pc_id);
686  return $plugged;
687 
688  //Page-Layout-Support
689  case "PlaceHolder":
690  require_once("./Services/COPage/classes/class.ilPCPlaceHolder.php");
691  $placeholder = new ilPCPlaceHolder($this->dom);
692  $placeholder->setNode($cont_node);
693  $placeholder->setHierId($a_hier_id);
694  $placeholder->setPcId($a_pc_id);
695  return $placeholder;
696 
697  case "ContentInclude":
698  require_once("./Services/COPage/classes/class.ilPCContentInclude.php");
699  $inc =& new ilPCContentInclude($this->dom);
700  $inc->setNode($cont_node);
701  $inc->setHierId($a_hier_id);
702  $inc->setPcId($a_pc_id);
703  return $inc;
704  }
705  break;
706 
707  case "TableData":
708  require_once("./Services/COPage/classes/class.ilPCTableData.php");
709  $td =& new ilPCTableData($this->dom);
710  $td->setNode($cont_node);
711  $td->setHierId($a_hier_id);
712  return $td;
713 
714  case "ListItem":
715  require_once("./Services/COPage/classes/class.ilPCListItem.php");
716  $td =& new ilPCListItem($this->dom);
717  $td->setNode($cont_node);
718  $td->setHierId($a_hier_id);
719  return $td;
720 
721  case "FileItem":
722  require_once("./Services/COPage/classes/class.ilPCFileItem.php");
723  $file_item =& new ilPCFileItem($this->dom);
724  $file_item->setNode($cont_node);
725  $file_item->setHierId($a_hier_id);
726  return $file_item;
727 
728  case "Tab":
729  require_once("./Services/COPage/classes/class.ilPCTab.php");
730  $tab =& new ilPCTab($this->dom);
731  $tab->setNode($cont_node);
732  $tab->setHierId($a_hier_id);
733  return $file_item;
734 
735  }
736  }
737 
738  function &getContentNode($a_hier_id, $a_pc_id = "")
739  {
740  $xpc = xpath_new_context($this->dom);
741  if($a_hier_id == "pg")
742  {
743  return $this->node;
744  }
745  else
746  {
747  // get per pc id
748  if ($a_pc_id != "")
749  {
750  $path = "//*[@PCID = '$a_pc_id']";
751  $res =& xpath_eval($xpc, $path);
752  if (count($res->nodeset) == 1)
753  {
754  $cont_node =& $res->nodeset[0];
755  return $cont_node;
756  }
757  }
758 
759  // fall back to hier id
760  $path = "//*[@HierId = '$a_hier_id']";
761  $res =& xpath_eval($xpc, $path);
762  if (count($res->nodeset) == 1)
763  {
764  $cont_node =& $res->nodeset[0];
765  return $cont_node;
766  }
767  }
768  }
769 
770  // only for test purposes
771  function lookforhier($a_hier_id)
772  {
773  $xpc = xpath_new_context($this->dom);
774  $path = "//*[@HierId = '$a_hier_id']";
775  $res =& xpath_eval($xpc, $path);
776  if (count($res->nodeset) == 1)
777  return "YES";
778  else
779  return "NO";
780  }
781 
782 
783  function &getNode()
784  {
785  return $this->node;
786  }
787 
788 
797  function setXMLContent($a_xml, $a_encoding = "UTF-8")
798  {
799  $this->encoding = $a_encoding;
800  $this->xml = $a_xml;
801  }
802 
809  function appendXMLContent($a_xml)
810  {
811  $this->xml.= $a_xml;
812  }
813 
814 
818  function getXMLContent($a_incl_head = false)
819  {
820  // build full http path for XML DOCTYPE header.
821  // Under windows a relative path doesn't work :-(
822  if($a_incl_head)
823  {
824 //echo "+".$this->encoding."+";
825  $enc_str = (!empty($this->encoding))
826  ? "encoding=\"".$this->encoding."\""
827  : "";
828  return "<?xml version=\"1.0\" $enc_str ?>".
829  "<!DOCTYPE PageObject SYSTEM \"".ILIAS_ABSOLUTE_PATH."/xml/".$this->cur_dtd."\">".
830  $this->xml;
831  }
832  else
833  {
834  return $this->xml;
835  }
836  }
837 
842  function copyXmlContent($a_new_question_copies = true)
843  {
844  $xml = $this->getXmlContent();
845  $temp_dom = domxml_open_mem('<?xml version="1.0" encoding="UTF-8"?>'.$xml,
847 
848  if(empty($error))
849  {
850  if ($a_new_question_copies)
851  {
852  $this->newQuestionCopies($temp_dom);
853  }
854  }
855  $xml = $temp_dom->dump_mem(0, $this->encoding);
856  $xml = eregi_replace("<\?xml[^>]*>","",$xml);
857  $xml = eregi_replace("<!DOCTYPE[^>]*>","",$xml);
858 
859  return $xml;
860  }
861 
866  function newQuestionCopies(&$temp_dom)
867  {
868  // Get question IDs
869  $path = "//Question";
870  $xpc = xpath_new_context($temp_dom);
871  $res = & xpath_eval($xpc, $path);
872 
873  $q_ids = array();
874  include_once("./Services/COPage/classes/class.ilInternalLink.php");
875  for ($i = 0; $i < count ($res->nodeset); $i++)
876  {
877  $qref = $res->nodeset[$i]->get_attribute("QRef");
878 
879  $inst_id = ilInternalLink::_extractInstOfTarget($qref);
881 
882  if (!($inst_id > 0))
883  {
884  if ($q_id > 0)
885  {
886  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
887  $question = assQuestion::_instanciateQuestion($q_id);
888 
889  // now copy this question and change reference to
890  // new question id
891  $duplicate_id = $question->duplicate(false);
892  $res->nodeset[$i]->set_attribute("QRef", "il__qst_".$duplicate_id);
893  }
894  }
895  }
896  }
897 
902  function getXMLFromDom($a_incl_head = false, $a_append_mobs = false, $a_append_bib = false,
903  $a_append_str = "", $a_omit_pageobject_tag = false)
904  {
905  if ($a_incl_head)
906  {
907 //echo "\n<br>#".$this->encoding."#";
908  return $this->dom->dump_mem(0, $this->encoding);
909  }
910  else
911  {
912  // append multimedia object elements
913  if ($a_append_mobs || $a_append_bib || $a_append_link_info)
914  {
915  $mobs = "";
916  $bibs = "";
917  if ($a_append_mobs)
918  {
919  $mobs =& $this->getMultimediaXML();
920  }
921  if ($a_append_bib)
922  {
923  $bibs =& $this->getBibliographyXML();
924  }
925  $trans =& $this->getLanguageVariablesXML();
926  return "<dummy>".$this->dom->dump_node($this->node).$mobs.$bibs.$trans.$a_append_str."</dummy>";
927  }
928  else
929  {
930  if (is_object($this->dom))
931  {
932  if ($a_omit_pageobject_tag)
933  {
934  $xml = "";
935  $childs =& $this->node->child_nodes();
936  for($i = 0; $i < count($childs); $i++)
937  {
938  $xml.= $this->dom->dump_node($childs[$i]);
939  }
940  return $xml;
941  }
942  else
943  {
944  $xml = $this->dom->dump_mem(0, $this->encoding);
945  $xml = eregi_replace("<\?xml[^>]*>","",$xml);
946  $xml = eregi_replace("<!DOCTYPE[^>]*>","",$xml);
947 
948  return $xml;
949 
950  // don't use dump_node. This gives always entities.
951  //return $this->dom->dump_node($this->node);
952  }
953  }
954  else
955  {
956  return "";
957  }
958  }
959  }
960  }
961 
966  {
967  global $lng;
968 
969  $xml = "<LVs>";
970  $lang_vars = array("ed_insert_par", "ed_insert_code",
971  "ed_insert_dtable", "ed_insert_atable", "ed_insert_media", "ed_insert_list",
972  "ed_insert_filelist", "ed_paste_clip", "ed_edit", "ed_insert_section",
973  "ed_edit_prop","ed_edit_files", "ed_edit_data", "ed_delete", "ed_moveafter", "ed_movebefore",
974  "ed_go", "ed_new_row_after", "ed_new_row_before",
975  "ed_new_col_after", "ed_new_col_before", "ed_delete_col",
976  "ed_delete_row", "ed_class", "ed_width", "ed_align_left",
977  "ed_align_right", "ed_align_center", "ed_align_left_float",
978  "ed_align_right_float", "ed_delete_item", "ed_new_item_before",
979  "ed_new_item_after", "ed_copy_clip", "please_select", "ed_split_page",
980  "ed_item_up", "ed_item_down", "ed_row_up", "ed_row_down",
981  "ed_col_left", "ed_col_right", "ed_split_page_next","ed_enable",
982  "de_activate", "ed_insert_repobj", "ed_insert_map", "ed_insert_tabs",
983  "ed_insert_pcqst", "empty_question", "ed_paste","question_placeh","media_placeh","text_placeh",
984  "ed_insert_plach","question_placehl","media_placehl","text_placehl",
985  "pc_flist", "pc_par", "pc_mob", "pc_qst", "pc_sec", "pc_dtab", "pc_tab",
986  "pc_code", "pc_vacc", "pc_hacc", "pc_res", "pc_map", "pc_list", "ed_insert_incl", "pc_incl");
987 
988  foreach ($lang_vars as $lang_var)
989  {
990  $this->appendLangVarXML($xml, $lang_var);
991  }
992 
993  $xml.= "</LVs>";
994 
995  return $xml;
996  }
997 
998  function appendLangVarXML(&$xml, $var)
999  {
1000  global $lng;
1001 
1002  $xml.= "<LV name=\"$var\" value=\"".$lng->txt("cont_".$var)."\"/>";
1003  }
1004 
1006  {
1007  require_once("./Services/COPage/classes/class.ilPCParagraph.php");
1008  $xpc = xpath_new_context($this->dom);
1009  $path = "//Paragraph[1]";
1010  $res =& xpath_eval($xpc, $path);
1011  if (count($res->nodeset) > 0)
1012  {
1013  $cont_node =& $res->nodeset[0]->parent_node();
1014  $par =& new ilPCParagraph($this->dom);
1015  $par->setNode($cont_node);
1016  return $par->getText();
1017  }
1018  else
1019  {
1020  return "";
1021  }
1022  }
1023 
1030  function setParagraphContent($a_hier_id, $a_content)
1031  {
1032  $node = $this->getContentNode($a_hier_id);
1033  if (is_object($node))
1034  {
1035  $node->set_content($a_content);
1036  }
1037  }
1038 
1039 
1048  function setContainsIntLink($a_contains_link)
1049  {
1050  $this->contains_int_link = $a_contains_link;
1051  }
1052 
1057  function containsIntLink()
1058  {
1059  return $this->contains_int_link;
1060  }
1061 
1062  function needsImportParsing($a_parse = "")
1063  {
1064 
1065  if ($a_parse === true)
1066  {
1067  $this->needs_parsing = true;
1068  }
1069  if ($a_parse === false)
1070  {
1071  $this->needs_parsing = false;
1072  }
1073  return $this->needs_parsing;
1074  }
1075 
1081  {
1082  global $ilias, $ilDB;
1083 
1084  // todo: access to $_GET and $_POST variables is not
1085  // allowed in non GUI classes!
1086  //
1087  // access to db table object_reference is not allowed here!
1088  $r = $ilias->db->query("SELECT * FROM object_reference WHERE ref_id=".
1089  $ilDB->quote($_GET["ref_id"],'integer'));
1090  $row = $r->fetchRow(DB_FETCHMODE_ASSOC);
1091 
1092  include_once("./classes/class.ilNestedSetXML.php");
1093  $nested = new ilNestedSetXML();
1094  $bibs_xml = $nested->export($row["obj_id"], "bib");
1095 
1096  return $bibs_xml;
1097  }
1098 
1099 
1104  function collectMediaObjects($a_inline_only = true)
1105  {
1106 //echo htmlentities($this->getXMLFromDom());
1107  // determine all media aliases of the page
1108  $xpc = xpath_new_context($this->dom);
1109  $path = "//MediaObject/MediaAlias";
1110  $res =& xpath_eval($xpc, $path);
1111  $mob_ids = array();
1112  for($i = 0; $i < count($res->nodeset); $i++)
1113  {
1114  $id_arr = explode("_", $res->nodeset[$i]->get_attribute("OriginId"));
1115  $mob_id = $id_arr[count($id_arr) - 1];
1116  $mob_ids[$mob_id] = $mob_id;
1117  }
1118 
1119  // determine all inline internal media links
1120  $xpc = xpath_new_context($this->dom);
1121  $path = "//IntLink[@Type = 'MediaObject']";
1122  $res =& xpath_eval($xpc, $path);
1123 
1124  for($i = 0; $i < count($res->nodeset); $i++)
1125  {
1126  if (($res->nodeset[$i]->get_attribute("TargetFrame") == "") ||
1127  (!$a_inline_only))
1128  {
1129  $target = $res->nodeset[$i]->get_attribute("Target");
1130  $id_arr = explode("_", $target);
1131  if (($id_arr[1] == IL_INST_ID) ||
1132  (substr($target, 0, 4) == "il__"))
1133  {
1134  $mob_id = $id_arr[count($id_arr) - 1];
1135  if (ilObject::_exists($mob_id))
1136  {
1137  $mob_ids[$mob_id] = $mob_id;
1138  }
1139  }
1140  }
1141  }
1142 
1143  return $mob_ids;
1144  }
1145 
1146 
1150  function getInternalLinks()
1151  {
1152  // get all internal links of the page
1153  $xpc = xpath_new_context($this->dom);
1154  $path = "//IntLink";
1155  $res =& xpath_eval($xpc, $path);
1156 
1157  $links = array();
1158  for($i = 0; $i < count($res->nodeset); $i++)
1159  {
1160  $target = $res->nodeset[$i]->get_attribute("Target");
1161  $type = $res->nodeset[$i]->get_attribute("Type");
1162  $targetframe = $res->nodeset[$i]->get_attribute("TargetFrame");
1163  $anchor = $res->nodeset[$i]->get_attribute("Anchor");
1164  $links[$target.":".$type.":".$targetframe.":".$anchor] =
1165  array("Target" => $target, "Type" => $type,
1166  "TargetFrame" => $targetframe, "Anchor" => $anchor);
1167 
1168  // get links (image map areas) for inline media objects
1169  if ($type == "MediaObject" && $targetframe == "")
1170  {
1171  if (substr($target, 0, 4) =="il__")
1172  {
1173  $id_arr = explode("_", $target);
1174  $id = $id_arr[count($id_arr) - 1];
1175 
1176  $med_links = ilMediaItem::_getMapAreasIntLinks($id);
1177  foreach($med_links as $key => $med_link)
1178  {
1179  $links[$key] = $med_link;
1180  }
1181  }
1182 
1183  }
1184 //echo "<br>-:".$target.":".$type.":".$targetframe.":-";
1185  }
1186  unset($xpc);
1187 
1188  // get all media aliases
1189  $xpc = xpath_new_context($this->dom);
1190  $path = "//MediaAlias";
1191  $res =& xpath_eval($xpc, $path);
1192 
1193  require_once("Services/MediaObjects/classes/class.ilMediaItem.php");
1194  for($i = 0; $i < count($res->nodeset); $i++)
1195  {
1196  $oid = $res->nodeset[$i]->get_attribute("OriginId");
1197  if (substr($oid, 0, 4) =="il__")
1198  {
1199  $id_arr = explode("_", $oid);
1200  $id = $id_arr[count($id_arr) - 1];
1201 
1202  $med_links = ilMediaItem::_getMapAreasIntLinks($id);
1203  foreach($med_links as $key => $med_link)
1204  {
1205  $links[$key] = $med_link;
1206  }
1207  }
1208  }
1209  unset($xpc);
1210 
1211  return $links;
1212  }
1213 
1217  function collectFileItems($a_xml = "")
1218  {
1219 //echo "<br>PageObject::collectFileItems[".$this->getId()."]";
1220  // determine all media aliases of the page
1221  if ($a_xml == "")
1222  {
1223  $xpc = xpath_new_context($this->dom);
1224  $path = "//FileItem/Identifier";
1225  $res =& xpath_eval($xpc, $path);
1226  }
1227  else
1228  {
1229  $doc = domxml_open_mem($a_xml);
1230  $xpc = xpath_new_context($doc);
1231  $path = "//FileItem/Identifier";
1232  $res =& xpath_eval($xpc, $path);
1233  }
1234  $file_ids = array();
1235  for($i = 0; $i < count($res->nodeset); $i++)
1236  {
1237  $id_arr = explode("_", $res->nodeset[$i]->get_attribute("Entry"));
1238  $file_id = $id_arr[count($id_arr) - 1];
1239  $file_ids[$file_id] = $file_id;
1240  }
1241 
1242  return $file_ids;
1243  }
1244 
1249  function getMultimediaXML()
1250  {
1251  $mob_ids = $this->collectMediaObjects();
1252 
1253  // get xml of corresponding media objects
1254  $mobs_xml = "";
1255  require_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
1256  foreach($mob_ids as $mob_id => $dummy)
1257  {
1258  if (ilObject::_lookupType($mob_id) == "mob")
1259  {
1260  $mob_obj =& new ilObjMediaObject($mob_id);
1261  $mobs_xml .= $mob_obj->getXML(IL_MODE_OUTPUT);
1262  }
1263  }
1264 //var_dump($mobs_xml);
1265  return $mobs_xml;
1266  }
1267 
1271  function getMediaAliasElement($a_mob_id, $a_nr = 1)
1272  {
1273  $xpc = xpath_new_context($this->dom);
1274  $path = "//MediaObject/MediaAlias[@OriginId='il__mob_$a_mob_id']";
1275  $res =& xpath_eval($xpc, $path);
1276  $mal_node =& $res->nodeset[$a_nr - 1];
1277  $mob_node =& $mal_node->parent_node();
1278 
1279  return $this->dom->dump_node($mob_node);
1280  }
1281 
1287  function validateDom()
1288  {
1289  $this->stripHierIDs();
1290  $this->dom->validate($error);
1291  return $error;
1292  }
1293 
1309  function addHierIDs()
1310  {
1311  $this->hier_ids = array();
1312  $this->first_row_ids = array();
1313  $this->first_col_ids = array();
1314  $this->list_item_ids = array();
1315  $this->file_item_ids = array();
1316 
1317  // set hierarchical ids for Paragraphs, Tables, TableRows and TableData elements
1318  $xpc = xpath_new_context($this->dom);
1319  //$path = "//Paragraph | //Table | //TableRow | //TableData";
1320 
1321  $sep = $path = "";
1322  foreach ($this->id_elements as $el)
1323  {
1324  $path.= $sep."//".$el;
1325  $sep = " | ";
1326  }
1327 
1328  $res =& xpath_eval($xpc, $path);
1329  for($i = 0; $i < count($res->nodeset); $i++)
1330  {
1331  $cnode = $res->nodeset[$i];
1332  $ctag = $cnode->node_name();
1333 
1334  // get hierarchical id of previous sibling
1335  $sib_hier_id = "";
1336  while($cnode =& $cnode->previous_sibling())
1337  {
1338  if (($cnode->node_type() == XML_ELEMENT_NODE)
1339  && $cnode->has_attribute("HierId"))
1340  {
1341  $sib_hier_id = $cnode->get_attribute("HierId");
1342  //$sib_hier_id = $id_attr->value();
1343  break;
1344  }
1345  }
1346 
1347  if ($sib_hier_id != "") // set id to sibling id "+ 1"
1348  {
1349  require_once("./Services/COPage/classes/class.ilPageContent.php");
1350  $node_hier_id = ilPageContent::incEdId($sib_hier_id);
1351  $res->nodeset[$i]->set_attribute("HierId", $node_hier_id);
1352  $this->hier_ids[] = $node_hier_id;
1353  if ($ctag == "TableData")
1354  {
1355  if (substr($par_hier_id,strlen($par_hier_id)-2) == "_1")
1356  {
1357  $this->first_row_ids[] = $node_hier_id;
1358  }
1359  }
1360  if ($ctag == "ListItem")
1361  {
1362  $this->list_item_ids[] = $node_hier_id;
1363  }
1364  if ($ctag == "FileItem")
1365  {
1366  $this->file_item_ids[] = $node_hier_id;
1367  }
1368  }
1369  else // no sibling -> node is first child
1370  {
1371  // get hierarchical id of next parent
1372  $cnode = $res->nodeset[$i];
1373  $par_hier_id = "";
1374  while($cnode =& $cnode->parent_node())
1375  {
1376  if (($cnode->node_type() == XML_ELEMENT_NODE)
1377  && $cnode->has_attribute("HierId"))
1378  {
1379  $par_hier_id = $cnode->get_attribute("HierId");
1380  //$par_hier_id = $id_attr->value();
1381  break;
1382  }
1383  }
1384 //echo "<br>par:".$par_hier_id." ($ctag)";
1385  if (($par_hier_id != "") && ($par_hier_id != "pg")) // set id to parent_id."_1"
1386  {
1387  $node_hier_id = $par_hier_id."_1";
1388  $res->nodeset[$i]->set_attribute("HierId", $node_hier_id);
1389  $this->hier_ids[] = $node_hier_id;
1390  if ($ctag == "TableData")
1391  {
1392  $this->first_col_ids[] = $node_hier_id;
1393  if (substr($par_hier_id,strlen($par_hier_id)-2) == "_1")
1394  {
1395  $this->first_row_ids[] = $node_hier_id;
1396  }
1397  }
1398  if ($ctag == "ListItem")
1399  {
1400  $this->list_item_ids[] = $node_hier_id;
1401  }
1402  if ($ctag == "FileItem")
1403  {
1404  $this->file_item_ids[] = $node_hier_id;
1405  }
1406 
1407  }
1408  else // no sibling, no parent -> first node
1409  {
1410  $node_hier_id = "1";
1411  $res->nodeset[$i]->set_attribute("HierId", $node_hier_id);
1412  $this->hier_ids[] = $node_hier_id;
1413  }
1414  }
1415  }
1416 
1417  // set special hierarchical id "pg" for pageobject
1418  $xpc = xpath_new_context($this->dom);
1419  $path = "//PageObject";
1420  $res =& xpath_eval($xpc, $path);
1421  for($i = 0; $i < count($res->nodeset); $i++) // should only be 1
1422  {
1423  $res->nodeset[$i]->set_attribute("HierId", "pg");
1424  $this->hier_ids[] = "pg";
1425  }
1426  unset($xpc);
1427  }
1428 
1432  function getHierIds()
1433  {
1434  return $this->hier_ids;
1435  }
1436 
1440  function getFirstRowIds()
1441  {
1442  return $this->first_row_ids;
1443  }
1444 
1449  {
1450  return $this->first_col_ids;
1451  }
1452 
1456  function getListItemIds()
1457  {
1458  return $this->list_item_ids;
1459  }
1460 
1464  function getFileItemIds()
1465  {
1466  return $this->file_item_ids;
1467  }
1468 
1472  function stripHierIDs()
1473  {
1474  if(is_object($this->dom))
1475  {
1476  $xpc = xpath_new_context($this->dom);
1477  $path = "//*[@HierId]";
1478  $res =& xpath_eval($xpc, $path);
1479  for($i = 0; $i < count($res->nodeset); $i++) // should only be 1
1480  {
1481  if ($res->nodeset[$i]->has_attribute("HierId"))
1482  {
1483  $res->nodeset[$i]->remove_attribute("HierId");
1484  }
1485  }
1486  unset($xpc);
1487  }
1488  }
1489 
1493  function addFileSizes()
1494  {
1495  $xpc = xpath_new_context($this->dom);
1496  $path = "//FileItem";
1497  $res =& xpath_eval($xpc, $path);
1498  for($i = 0; $i < count($res->nodeset); $i++)
1499  {
1500  $cnode =& $res->nodeset[$i];
1501  $size_node =& $this->dom->create_element("Size");
1502  $size_node =& $cnode->append_child($size_node);
1503 
1504  $childs =& $cnode->child_nodes();
1505  $size = "";
1506  for($j = 0; $j < count($childs); $j++)
1507  {
1508  if ($childs[$j]->node_name() == "Identifier")
1509  {
1510  if ($childs[$j]->has_attribute("Entry"))
1511  {
1512  $entry = $childs[$j]->get_attribute("Entry");
1513  $entry_arr = explode("_", $entry);
1514  $id = $entry_arr[count($entry_arr) - 1];
1515  require_once("./Modules/File/classes/class.ilObjFile.php");
1517  }
1518  }
1519  }
1520  $size_node->set_content($size);
1521  }
1522 
1523  unset($xpc);
1524  }
1525 
1530  function resolveIntLinks()
1531  {
1532  // resolve normal internal links
1533  $xpc = xpath_new_context($this->dom);
1534  $path = "//IntLink";
1535  $res =& xpath_eval($xpc, $path);
1536  for($i = 0; $i < count($res->nodeset); $i++)
1537  {
1538  $target = $res->nodeset[$i]->get_attribute("Target");
1539  $type = $res->nodeset[$i]->get_attribute("Type");
1540 
1541  $new_target = ilInternalLink::_getIdForImportId($type, $target);
1542  if ($new_target !== false)
1543  {
1544  $res->nodeset[$i]->set_attribute("Target", $new_target);
1545  }
1546  else // check wether link target is same installation
1547  {
1548  if (ilInternalLink::_extractInstOfTarget($target) == IL_INST_ID &&
1549  IL_INST_ID > 0 && $type != "RepositoryItem")
1550  {
1551  $new_target = ilInternalLink::_removeInstFromTarget($target);
1552  if (ilInternalLink::_exists($type, $new_target))
1553  {
1554  $res->nodeset[$i]->set_attribute("Target", $new_target);
1555  }
1556  }
1557  }
1558 
1559  }
1560  unset($xpc);
1561 
1562  // resolve internal links in map areas
1563  $xpc = xpath_new_context($this->dom);
1564  $path = "//MediaAlias";
1565  $res =& xpath_eval($xpc, $path);
1566 //echo "<br><b>page::resolve</b><br>";
1567 //echo "Content:".htmlentities($this->getXMLFromDOM()).":<br>";
1568  for($i = 0; $i < count($res->nodeset); $i++)
1569  {
1570  $orig_id = $res->nodeset[$i]->get_attribute("OriginId");
1571  $id_arr = explode("_", $orig_id);
1572  $mob_id = $id_arr[count($id_arr) - 1];
1574  }
1575  }
1576 
1583  function moveIntLinks($a_from_to)
1584  {
1585  $this->buildDom();
1586 
1587  $changed = false;
1588 
1589  // resolve normal internal links
1590  $xpc = xpath_new_context($this->dom);
1591  $path = "//IntLink";
1592  $res =& xpath_eval($xpc, $path);
1593  for($i = 0; $i < count($res->nodeset); $i++)
1594  {
1595  $target = $res->nodeset[$i]->get_attribute("Target");
1596  $type = $res->nodeset[$i]->get_attribute("Type");
1597  $obj_id = ilInternalLink::_extractObjIdOfTarget($target);
1598  if ($a_from_to[$obj_id] > 0 && is_int(strpos($target, "__")))
1599  {
1600  if ($type == "PageObject" && ilLMObject::_lookupType($a_from_to[$obj_id]) == "pg")
1601  {
1602  $res->nodeset[$i]->set_attribute("Target", "il__pg_".$a_from_to[$obj_id]);
1603  $changed = true;
1604  }
1605  if ($type == "StructureObject" && ilLMObject::_lookupType($a_from_to[$obj_id]) == "st")
1606  {
1607  $res->nodeset[$i]->set_attribute("Target", "il__st_".$a_from_to[$obj_id]);
1608  $changed = true;
1609  }
1610  }
1611  }
1612  unset($xpc);
1613 
1614  // map areas
1615  $this->addHierIDs();
1616  $xpc = xpath_new_context($this->dom);
1617  $path = "//MediaAlias";
1618  $res =& xpath_eval($xpc, $path);
1619 
1620  require_once("Services/MediaObjects/classes/class.ilMediaItem.php");
1621  require_once("Services/COPage/classes/class.ilMediaAliasItem.php");
1622 
1623  for($i = 0; $i < count($res->nodeset); $i++)
1624  {
1625  $media_object_node = $res->nodeset[$i]->parent_node();
1626  $page_content_node = $media_object_node->parent_node();
1627  $c_hier_id = $page_content_node->get_attribute("HierId");
1628 
1629  // first check, wheter we got instance map areas -> take these
1630  $std_alias_item = new ilMediaAliasItem($this->dom,
1631  $c_hier_id, "Standard");
1632  $areas = $std_alias_item->getMapAreas();
1633  $correction_needed = false;
1634  if (count($areas) > 0)
1635  {
1636  // check if correction needed
1637  foreach($areas as $area)
1638  {
1639  if ($area["Type"] == "PageObject" ||
1640  $area["Type"] == "StructureObject")
1641  {
1642  $t = $area["Target"];
1643  $tid = _extractObjIdOfTarget($t);
1644  if ($a_from_to[$tid] > 0)
1645  {
1646  $correction_needed = true;
1647  }
1648  }
1649  }
1650  }
1651  else
1652  {
1653  $areas = array();
1654 
1655  // get object map areas and check whether at least one must
1656  // be corrected
1657  $oid = $res->nodeset[$i]->get_attribute("OriginId");
1658  if (substr($oid, 0, 4) =="il__")
1659  {
1660  $id_arr = explode("_", $oid);
1661  $id = $id_arr[count($id_arr) - 1];
1662 
1663  $mob = new ilObjMediaObject($id);
1664  $med_item = $mob->getMediaItem("Standard");
1665  $med_areas = $med_item->getMapAreas();
1666 
1667  foreach($med_areas as $area)
1668  {
1669  $link_type = ($area->getLinkType() == "int")
1670  ? "IntLink"
1671  : "ExtLink";
1672 
1673  $areas[] = array(
1674  "Nr" => $area->getNr(),
1675  "Shape" => $area->getShape(),
1676  "Coords" => $area->getCoords(),
1677  "Link" => array(
1678  "LinkType" => $link_type,
1679  "Href" => $area->getHref(),
1680  "Title" => $area->getTitle(),
1681  "Target" => $area->getTarget(),
1682  "Type" => $area->getType(),
1683  "TargetFrame" => $area->getTargetFrame()
1684  )
1685  );
1686 
1687  if ($area->getType() == "PageObject" ||
1688  $area->getType() == "StructureObject")
1689  {
1690  $t = $area->getTarget();
1692  if ($a_from_to[$tid] > 0)
1693  {
1694  $correction_needed = true;
1695  }
1696 //var_dump($a_from_to);
1697  }
1698  }
1699  }
1700  }
1701 
1702  // correct map area links
1703  if ($correction_needed)
1704  {
1705  $changed = true;
1706  $std_alias_item->deleteAllMapAreas();
1707  foreach($areas as $area)
1708  {
1709  if ($area["Link"]["LinkType"] == "IntLink")
1710  {
1711  $target = $area["Link"]["Target"];
1712  $type = $area["Link"]["Type"];
1713  $obj_id = ilInternalLink::_extractObjIdOfTarget($target);
1714  if ($a_from_to[$obj_id] > 0)
1715  {
1716  if ($type == "PageObject" && ilLMObject::_lookupType($a_from_to[$obj_id]) == "pg")
1717  {
1718  $area["Link"]["Target"] = "il__pg_".$a_from_to[$obj_id];
1719  }
1720  if ($type == "StructureObject" && ilLMObject::_lookupType($a_from_to[$obj_id]) == "st")
1721  {
1722  $area["Link"]["Target"] = "il__st_".$a_from_to[$obj_id];
1723  }
1724  }
1725  }
1726 
1727  $std_alias_item->addMapArea($area["Shape"], $area["Coords"],
1728  $area["Link"]["Title"],
1729  array( "Type" => $area["Link"]["Type"],
1730  "TargetFrame" => $area["Link"]["TargetFrame"],
1731  "Target" => $area["Link"]["Target"],
1732  "Href" => $area["Link"]["Href"],
1733  "LinkType" => $area["Link"]["LinkType"],
1734  ));
1735  }
1736  }
1737  }
1738  unset($xpc);
1739 
1740  return $changed;
1741  }
1742 
1748  static function _handleImportRepositoryLinks($a_rep_import_id, $a_rep_type, $a_rep_ref_id)
1749  {
1750  include_once("./Services/COPage/classes/class.ilInternalLink.php");
1751 
1752 //echo "-".$a_rep_import_id."-".$a_rep_ref_id."-";
1753  $sources = ilInternalLink::_getSourcesOfTarget("obj",
1754  ilInternalLink::_extractObjIdOfTarget($a_rep_import_id),
1755  ilInternalLink::_extractInstOfTarget($a_rep_import_id));
1756 //var_dump($sources);
1757  foreach($sources as $source)
1758  {
1759 //echo "A";
1760  if ($source["type"] == "lm:pg")
1761  {
1762 //echo "B";
1763  $page_obj = new ilPageObject("lm", $source["id"], false);
1764  if (!$page_obj->page_not_found)
1765  {
1766 //echo "C";
1767  $page_obj->handleImportRepositoryLink($a_rep_import_id,
1768  $a_rep_type, $a_rep_ref_id);
1769  }
1770  $page_obj->update();
1771  }
1772  }
1773  }
1774 
1775  function handleImportRepositoryLink($a_rep_import_id, $a_rep_type, $a_rep_ref_id)
1776  {
1777  $this->buildDom();
1778 
1779  // resolve normal internal links
1780  $xpc = xpath_new_context($this->dom);
1781  $path = "//IntLink";
1782  $res =& xpath_eval($xpc, $path);
1783 //echo "1";
1784  for($i = 0; $i < count($res->nodeset); $i++)
1785  {
1786 //echo "2";
1787  $target = $res->nodeset[$i]->get_attribute("Target");
1788  $type = $res->nodeset[$i]->get_attribute("Type");
1789  if ($target == $a_rep_import_id && $type == "RepositoryItem")
1790  {
1791 //echo "setting:"."il__".$a_rep_type."_".$a_rep_ref_id;
1792  $res->nodeset[$i]->set_attribute("Target",
1793  "il__".$a_rep_type."_".$a_rep_ref_id);
1794  }
1795  }
1796  unset($xpc);
1797  }
1798 
1802  function createFromXML()
1803  {
1804  global $lng, $ilDB, $ilUser;
1805 
1806 //echo "<br>PageObject::createFromXML[".$this->getId()."]";
1807 
1808  if($this->getXMLContent() == "")
1809  {
1810  $this->setXMLContent("<PageObject></PageObject>");
1811  }
1812 
1813  $iel = $this->containsDeactivatedElements($this->getXMLContent());
1814  $inl = $this->containsIntLinks($this->getXMLContent());
1815 
1816  // create object
1817  /* $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 ".
1818  "(".$ilDB->quote($this->getId()).",".
1819  $ilDB->quote($this->getParentId()).",".
1820  $ilDB->quote($this->getXMLContent()).
1821  ", ".$ilDB->quote($this->getParentType()).
1822  ", ".$ilDB->quote($ilUser->getId()).
1823  ", ".$ilDB->quote($ilUser->getId()).
1824  ", ".$ilDB->quote($iel, "integer")." ".
1825  ", ".$ilDB->quote($inl, "integer")." ".
1826  ", now(), now())"; */
1827 
1828  $ilDB->insert("page_object", array(
1829  "page_id" => array("integer", $this->getId()),
1830  "parent_id" => array("integer", $this->getParentId()),
1831  "content" => array("clob", $this->getXMLContent()),
1832  "parent_type" => array("text", $this->getParentType()),
1833  "create_user" => array("integer", $ilUser->getId()),
1834  "last_change_user" => array("integer", $ilUser->getId()),
1835  "inactive_elements" => array("integer", $iel),
1836  "int_links" => array("integer", $inl),
1837  "created" => array("timestamp", ilUtil::now()),
1838  "last_change" => array("timestamp", ilUtil::now())
1839  ));
1840 
1841 // todo: put this into insert
1842 /* if(!$ilDB->checkQuerySize($query))
1843  {
1844  $this->ilias->raiseError($lng->txt("check_max_allowed_packet_size"),$this->ilias->error_obj->MESSAGE);
1845  return false;
1846  }*/
1847 
1848 // $ilDB->query($query);
1849  }
1850 
1851 
1855  function updateFromXML()
1856  {
1857  global $lng, $ilDB, $ilUser;
1858 
1859 //echo "<br>PageObject::updateFromXML[".$this->getId()."]";
1860 //echo "update:".ilUtil::prepareDBString(($this->getXMLContent())).":<br>";
1861 //echo "update:".htmlentities($this->getXMLContent()).":<br>";
1862 
1863  $iel = $this->containsDeactivatedElements($this->getXMLContent());
1864  $inl = $this->containsIntLinks($this->getXMLContent());
1865 
1866  /*$query = "UPDATE page_object ".
1867  "SET content = ".$ilDB->quote($this->getXMLContent())." ".
1868  ", parent_id = ".$ilDB->quote($this->getParentId())." ".
1869  ", last_change_user = ".$ilDB->quote($ilUser->getId())." ".
1870  ", last_change = now() ".
1871  ", active = ".$ilDB->quote($this->getActive())." ".
1872  ", activation_start = ".$ilDB->quote($this->getActivationStart())." ".
1873  ", activation_end = ".$ilDB->quote($this->getActivationEnd())." ".
1874  ", inactive_elements = ".$ilDB->quote($iel, "integer")." ".
1875  ", int_links = ".$ilDB->quote($inl, "integer")." ".
1876  "WHERE page_id = ".$ilDB->quote($this->getId())." AND parent_type=".
1877  $ilDB->quote($this->getParentType());*/
1878 
1879  $ilDB->update("page_object", array(
1880  "content" => array("clob", $this->getXMLContent()),
1881  "parent_id" => array("integer", $this->getParentId()),
1882  "last_change_user" => array("integer", $ilUser->getId()),
1883  "last_change" => array("timestamp", ilUtil::now()),
1884  "active" => array("integer", $this->getActive()),
1885  "activation_start" => array("timestamp", $this->getActivationStart()),
1886  "activation_end" => array("timestamp", $this->getActivationEnd()),
1887  "inactive_elements" => array("integer", $iel),
1888  "int_links" => array("integer", $inl),
1889  ), array(
1890  "page_id" => array("integer", $this->getId()),
1891  "parent_type" => array("text", $this->getParentType())
1892  ));
1893 
1894 // todo: move this to update
1895 /* if(!$ilDB->checkQuerySize($query))
1896  {
1897  $this->ilias->raiseError($lng->txt("check_max_allowed_packet_size"),$this->ilias->error_obj->MESSAGE);
1898  return false;
1899  }
1900  $ilDB->query($query);*/
1901 // save style usage
1902  $this->saveStyleUsage($this->getXMLContent());
1903 
1904  // save internal link information
1905  $this->saveInternalLinks($this->getXMLContent());
1906  return true;
1907  }
1908 
1912  function update($a_validate = true, $a_no_history = false, $skip_handle_usages = false)
1913  {
1914  global $lng, $ilDB, $ilUser, $ilLog, $ilCtrl;
1915 
1916 //echo "<br>**".$this->getId()."**";
1917 //echo "<br>PageObject::update[".$this->getId()."],validate($a_validate)";
1918 //echo "\n<br>dump_all2:".$this->dom->dump_mem(0, "UTF-8").":";
1919 //echo "\n<br>PageObject::update:".$this->getXMLFromDom().":";
1920 //echo "<br>PageObject::update:".htmlentities($this->getXMLFromDom());
1921 
1922  // add missing pc ids
1923  if (!$this->checkPCIds())
1924  {
1925  $this->insertPCIds();
1926  }
1927 
1928  // test validating
1929  if($a_validate)
1930  {
1931  $errors = $this->validateDom();
1932  }
1933 
1934 //echo "-".htmlentities($this->getXMLFromDom())."-"; exit;
1935  if(empty($errors))
1936  {
1937  $content = $this->getXMLFromDom();
1938 
1939  // this needs to be locked
1940 
1941  // write history entry
1942  $old_set = $ilDB->query("SELECT * FROM page_object WHERE ".
1943  "page_id = ".$ilDB->quote($this->getId(), "integer")." AND ".
1944  "parent_type = ".$ilDB->quote($this->getParentType(), "text"));
1945  $last_nr_set = $ilDB->query("SELECT max(nr) as mnr FROM page_history WHERE ".
1946  "page_id = ".$ilDB->quote($this->getId(), "integer")." AND ".
1947  "parent_type = ".$ilDB->quote($this->getParentType(), "text"));
1948  $last_nr = $ilDB->fetchAssoc($last_nr_set);
1949  if ($old_rec = $ilDB->fetchAssoc($old_set))
1950  {
1951  // only save, if something has changed and not in layout mode
1952  if (($content != $old_rec["content"]) && !$a_no_history &&
1953  !$this->history_saved && !$this->layout_mode)
1954  {
1955  if ($old_rec["content"] != "<PageObject></PageObject>")
1956  {
1957  $ilDB->manipulateF("DELETE FROM page_history WHERE ".
1958  "page_id = %s AND parent_type = %s AND hdate = %s",
1959  array("integer", "text", "timestamp"),
1960  array($old_rec["page_id"], $old_rec["parent_type"], $old_rec["last_change"]));
1961  $ilDB->insert("page_history", array(
1962  "page_id" => array("integer", $old_rec["page_id"]),
1963  "parent_type" => array("text", $old_rec["parent_type"]),
1964  "hdate" => array("timestamp", $old_rec["last_change"]),
1965  "parent_id" => array("integer", $old_rec["parent_id"]),
1966  "content" => array("clob", $old_rec["content"]),
1967  "user_id" => array("integer", $old_rec["last_change_user"]),
1968  "ilias_version" => array("text", ILIAS_VERSION_NUMERIC),
1969  "nr" => array("integer", (int) $last_nr["mnr"] + 1)
1970  ));
1971  /*$h_query = "REPLACE INTO page_history ".
1972  "(page_id, parent_type, hdate, parent_id, content, user_id, ilias_version, nr) VALUES (".
1973  $ilDB->quote($old_rec["page_id"]).",".
1974  $ilDB->quote($old_rec["parent_type"]).",".
1975  $ilDB->quote($old_rec["last_change"]).",".
1976  $ilDB->quote($old_rec["parent_id"]).",".
1977  $ilDB->quote($old_rec["content"]).",".
1978  $ilDB->quote($old_rec["last_change_user"]).",".
1979  $ilDB->quote(ILIAS_VERSION_NUMERIC).",".
1980  $ilDB->quote($last_nr["mnr"] + 1).")";
1981 //echo "<br><br>+$a_no_history+$h_query";
1982  $ilDB->query($h_query);*/
1983  $this->saveMobUsage($old_rec["content"], $last_nr["mnr"] + 1);
1984  $this->saveStyleUsage($old_rec["content"], $last_nr["mnr"] + 1);
1985  $this->saveFileUsage($old_rec["content"], $last_nr["mnr"] + 1);
1986  $this->saveContentIncludeUsage($old_rec["content"], $last_nr["mnr"] + 1);
1987  $this->history_saved = true; // only save one time
1988  }
1989  else
1990  {
1991  $this->history_saved = true; // do not save on first change
1992  }
1993  }
1994  }
1995 //echo htmlentities($content);
1996  $em = (trim($content) == "<PageObject/>")
1997  ? 1
1998  : 0;
1999 
2000  $iel = $this->containsDeactivatedElements($content);
2001  $inl = $this->containsIntLinks($content);
2002  /*$query = "UPDATE page_object ".
2003  "SET content = ".$ilDB->quote($content)." ".
2004  ", parent_id= ".$ilDB->quote($this->getParentId())." ".
2005  ", last_change_user= ".$ilDB->quote($ilUser->getId())." ".
2006  ", last_change = now() ".
2007  ", is_empty = ".$ilDB->quote($em, "integer")." ".
2008  ", active = ".$ilDB->quote($this->getActive())." ".
2009  ", activation_start = ".$ilDB->quote($this->getActivationStart())." ".
2010  ", activation_end = ".$ilDB->quote($this->getActivationEnd())." ".
2011  ", inactive_elements = ".$ilDB->quote($iel, "integer")." ".
2012  ", int_links = ".$ilDB->quote($inl, "integer")." ".
2013  " WHERE page_id = ".$ilDB->quote($this->getId()).
2014  " AND parent_type= ".$ilDB->quote($this->getParentType());*/
2015 
2016  $ilDB->update("page_object", array(
2017  "content" => array("clob", $content),
2018  "parent_id" => array("integer", $this->getParentId()),
2019  "last_change_user" => array("integer", $ilUser->getId()),
2020  "last_change" => array("timestamp", ilUtil::now()),
2021  "is_empty" => array("integer", $em),
2022  "active" => array("integer", $this->getActive()),
2023  "activation_start" => array("timestamp", $this->getActivationStart()),
2024  "activation_end" => array("timestamp", $this->getActivationEnd()),
2025  "inactive_elements" => array("integer", $iel),
2026  "int_links" => array("integer", $inl),
2027  ), array(
2028  "page_id" => array("integer", $this->getId()),
2029  "parent_type" => array("text", $this->getParentType())
2030  ));
2031 
2032 // todo put this into update function
2033 /* if(!$this->ilias->db->checkQuerySize($query))
2034  {
2035  $this->ilias->raiseError($lng->txt("check_max_allowed_packet_size"),$this->ilias->error_obj->MESSAGE);
2036  return false;
2037  }*/
2038 
2039 // $this->ilias->db->query($query);
2040 
2041  if (!$skip_handle_usages)
2042  {
2043  // handle media object usage
2044  include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
2046  $this->getParentType().":pg", $this->getId());
2047  $this->saveMobUsage($this->getXMLFromDom());
2048  $this->saveMetaKeywords($this->getXMLFromDom());
2049  foreach($mob_ids as $mob) // check, whether media object can be deleted
2050  {
2051  if (ilObject::_exists($mob) && ilObject::_lookupType($mob) == "mob")
2052  {
2053  $mob_obj = new ilObjMediaObject($mob);
2054  $usages = $mob_obj->getUsages(false);
2055  if (count($usages) == 0) // delete, if no usage exists
2056  {
2057  $mob_obj->delete();
2058  }
2059  }
2060  }
2061 
2062  // handle file usages
2063  include_once("./Modules/File/classes/class.ilObjFile.php");
2064  $file_ids = ilObjFile::_getFilesOfObject(
2065  $this->getParentType().":pg", $this->getId());
2066  $this->saveFileUsage();
2067  foreach($file_ids as $file) // check, whether file object can be deleted
2068  {
2069  if (ilObject::_exists($file))
2070  {
2071  $file_obj = new ilObjFile($file, false);
2072  $usages = $file_obj->getUsages();
2073  if (count($usages) == 0) // delete, if no usage exists
2074  {
2075  if ($file_obj->getMode() == "filelist") // non-repository object
2076  {
2077  $file_obj->delete();
2078  }
2079  }
2080  }
2081  }
2082 
2083  // save style usage
2084  $this->saveStyleUsage($this->getXMLFromDom());
2085 
2086  // save content include usage
2087  $this->saveContentIncludeUsage($this->getXMLFromDom());
2088  }
2089 
2090  // save internal link information
2091  $this->saveInternalLinks($this->getXMLFromDom());
2092  $this->saveAnchors($this->getXMLFromDom());
2093  $this->callUpdateListeners();
2094 //echo "<br>PageObject::update:".htmlentities($this->getXMLContent()).":";
2095  return true;
2096  }
2097  else
2098  {
2099  return $errors;
2100  }
2101  }
2102 
2103 
2107  function delete()
2108  {
2109  global $ilDB;
2110 
2111  $mobs = array();
2112  $files = array();
2113 
2114  if (!$this->page_not_found)
2115  {
2116  $this->buildDom();
2117  $mobs = $this->collectMediaObjects(false);
2118  $files = $this->collectFileItems();
2119  }
2120 
2121  // delete mob usages
2122  $this->saveMobUsage("<dummy></dummy>");
2123 
2124  // delete style usages
2125  $this->saveStyleUsage("<dummy></dummy>");
2126 
2127  // delete style usages
2128  $this->saveContentIncludeUsage("<dummy></dummy>");
2129 
2130  // delete internal links
2131  $this->saveInternalLinks("<dummy></dummy>");
2132 
2133  // delete anchors
2134  $this->saveAnchors("<dummy></dummy>");
2135 
2136  // delete all file usages
2137  include_once("./Modules/File/classes/class.ilObjFile.php");
2138  ilObjFile::_deleteAllUsages($this->getParentType().":pg", $this->getId());
2139 
2140  // delete page_object entry
2141  $ilDB->manipulate("DELETE FROM page_object ".
2142  "WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
2143  " AND parent_type= ".$ilDB->quote($this->getParentType(), "text"));
2144  //$this->ilias->db->query($query);
2145 
2146  // delete media objects
2147  foreach ($mobs as $mob_id)
2148  {
2149  if(ilObject::_lookupType($mob_id) != 'mob')
2150  {
2151  $GLOBALS['ilLog']->write(__METHOD__.': Type mismatch. Ignoring mob with id: '.$mob_id);
2152  continue;
2153  }
2154 
2155  if (ilObject::_exists($mob_id))
2156  {
2157  $mob_obj =& new ilObjMediaObject($mob_id);
2158  $mob_obj->delete();
2159  }
2160  }
2161 
2162  include_once("./Modules/File/classes/class.ilObjFile.php");
2163  foreach ($files as $file_id)
2164  {
2165  if (ilObject::_exists($file_id))
2166  {
2167  $file_obj =& new ilObjFile($file_id, false);
2168  $file_obj->delete();
2169  }
2170  }
2171 
2172  }
2173 
2179  function saveMetaKeywords($a_xml)
2180  {
2181  // not nice, should be set by context per method
2182  if ($this->getParentType() == "gdf" ||
2183  $this->getParentType() == "lm" ||
2184  $this->getParentType() == "dbk")
2185  {
2186  $doc = domxml_open_mem($a_xml);
2187 
2188  // get existing keywords
2189  $keywords = array();
2190 
2191  // find all Keyw tags
2192  $xpc = xpath_new_context($doc);
2193  $path = "//Keyw";
2194  $res = xpath_eval($xpc, $path);
2195  for ($i=0; $i < count($res->nodeset); $i++)
2196  {
2197  $k = trim(strip_tags($res->nodeset[$i]->get_content()));
2198  if (!in_array($k, $keywords))
2199  {
2200  $keywords[] = $k;
2201  }
2202  }
2203 
2204  $meta_type = ($this->getParentType() == "gdf")
2205  ? "gdf"
2206  : "pg";
2207  $meta_rep_id = $this->getParentId();
2208  $meta_id = $this->getId();
2209 
2210  include_once("./Services/MetaData/classes/class.ilMD.php");
2211  $md_obj = new ilMD($meta_rep_id, $meta_id, $meta_type);
2212  $mkeywords = array();
2213  $lang = "";
2214  if(is_object($md_section = $md_obj->getGeneral()))
2215  {
2216  foreach($ids = $md_section->getKeywordIds() as $id)
2217  {
2218  $md_key = $md_section->getKeyword($id);
2219  $mkeywords[] = strtolower($md_key->getKeyword());
2220  if ($lang == "")
2221  {
2222  $lang = $md_key->getKeywordLanguageCode();
2223  }
2224  }
2225  }
2226  if ($lang == "")
2227  {
2228  foreach($ids = $md_section->getLanguageIds() as $id)
2229  {
2230  $md_lang = $md_section->getLanguage($id);
2231  if ($lang == "")
2232  {
2233  $lang = $md_lang->getLanguageCode();
2234  }
2235  }
2236  }
2237  foreach ($keywords as $k)
2238  {
2239  if (!in_array(strtolower($k), $mkeywords))
2240  {
2241  if (trim($k) != "" && $lang != "")
2242  {
2243  $md_key = $md_section->addKeyword();
2244  $md_key->setKeyword(ilUtil::stripSlashes($k));
2245  $md_key->setKeywordLanguage(new ilMDLanguageItem($lang));
2246  $md_key->save();
2247  }
2248  $mkeywords[] = strtolower($k);
2249  }
2250  }
2251  }
2252  }
2253 
2259  function saveMobUsage($a_xml, $a_old_nr = 0)
2260  {
2261  $doc = domxml_open_mem($a_xml);
2262 
2263  // media aliases
2264  $xpc = xpath_new_context($doc);
2265  $path = "//MediaAlias";
2266  $res =& xpath_eval($xpc, $path);
2267  $usages = array();
2268  for ($i=0; $i < count($res->nodeset); $i++)
2269  {
2270  $id_arr = explode("_", $res->nodeset[$i]->get_attribute("OriginId"));
2271  $mob_id = $id_arr[count($id_arr) - 1];
2272  if ($mob_id > 0)
2273  {
2274  $usages[$mob_id] = true;
2275  }
2276  }
2277 
2278  // media objects
2279  $xpc = xpath_new_context($doc);
2280  $path = "//MediaObject/MetaData/General/Identifier";
2281  $res =& xpath_eval($xpc, $path);
2282  for ($i=0; $i < count($res->nodeset); $i++)
2283  {
2284  $mob_entry = $res->nodeset[$i]->get_attribute("Entry");
2285  $mob_arr = explode("_", $mob_entry);
2286  $mob_id = $mob_arr[count($mob_arr) - 1];
2287  if ($mob_id > 0)
2288  {
2289  $usages[$mob_id] = true;
2290  }
2291  }
2292 
2293  // internal links
2294  $xpc = xpath_new_context($doc);
2295  $path = "//IntLink[@Type='MediaObject']";
2296  $res =& xpath_eval($xpc, $path);
2297  for ($i=0; $i < count($res->nodeset); $i++)
2298  {
2299  $mob_target = $res->nodeset[$i]->get_attribute("Target");
2300  $mob_arr = explode("_", $mob_target);
2301  $mob_id = $mob_arr[count($mob_arr) - 1];
2302  if ($mob_id > 0)
2303  {
2304  $usages[$mob_id] = true;
2305  }
2306  }
2307 
2308  include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
2309  ilObjMediaObject::_deleteAllUsages($this->getParentType().":pg", $this->getId(), $a_old_nr);
2310  foreach($usages as $mob_id => $val)
2311  {
2312  ilObjMediaObject::_saveUsage($mob_id, $this->getParentType().":pg", $this->getId(), $a_old_nr);
2313  }
2314  }
2315 
2319  function saveFileUsage($a_xml = "", $a_old_nr = 0)
2320  {
2321  $file_ids = $this->collectFileItems($a_xml, $a_old_nr);
2322  include_once("./Modules/File/classes/class.ilObjFile.php");
2323  ilObjFile::_deleteAllUsages($this->getParentType().":pg", $this->getId(), $a_old_nr);
2324  foreach($file_ids as $file_id)
2325  {
2326  ilObjFile::_saveUsage($file_id, $this->getParentType().":pg", $this->getId(), $a_old_nr);
2327  }
2328  }
2329 
2333  function saveContentIncludeUsage($a_xml = "", $a_old_nr = 0)
2334  {
2335  include_once("./Services/COPage/classes/class.ilPageContentUsage.php");
2336  $ci_ids = $this->collectContentIncludes($a_xml);
2337  ilPageContentUsage::deleteAllUsages("incl", $this->getParentType().":pg", $this->getId(), $a_old_nr);
2338  foreach($ci_ids as $ci_id)
2339  {
2340  if ((int) $ci_id["inst_id"] <= 0)
2341  {
2342  ilPageContentUsage::saveUsage("incl", $ci_id["id"], $this->getParentType().":pg", $this->getId(), $a_old_nr);
2343  }
2344  }
2345  }
2346 
2350  function collectContentIncludes($a_xml = "")
2351  {
2352  // determine all media aliases of the page
2353  if ($a_xml == "")
2354  {
2355  $this->buildDom();
2356  $xpc = xpath_new_context($this->dom);
2357  $path = "//ContentInclude";
2358  $res =& xpath_eval($xpc, $path);
2359  }
2360  else
2361  {
2362  $doc = domxml_open_mem($a_xml);
2363  $xpc = xpath_new_context($doc);
2364  $path = "//ContentInclude";
2365  $res =& xpath_eval($xpc, $path);
2366  }
2367  $ci_ids = array();
2368  for($i = 0; $i < count($res->nodeset); $i++)
2369  {
2370  $type = $res->nodeset[$i]->get_attribute("ContentType");
2371  $id = $res->nodeset[$i]->get_attribute("ContentId");
2372  $inst_id = $res->nodeset[$i]->get_attribute("InstId");
2373  $ci_ids[$type.":".$id.":".$inst_id] = array(
2374  "type" => $type, "id" => $id, "inst_id" => $inst_id);
2375  }
2376 
2377  return $ci_ids;
2378  }
2379 
2380 
2386  function saveStyleUsage($a_xml, $a_old_nr = 0)
2387  {
2388  global $ilDB;
2389 
2390  $doc = domxml_open_mem($a_xml);
2391 
2392  // media aliases
2393  $xpc = xpath_new_context($doc);
2394  $path = "//Paragraph | //Section | //MediaAlias | //FileItem".
2395  " | //Table | //TableData | //Tabs | //List";
2396  $res = xpath_eval($xpc, $path);
2397  $usages = array();
2398  for ($i=0; $i < count($res->nodeset); $i++)
2399  {
2400  switch ($res->nodeset[$i]->node_name())
2401  {
2402  case "Paragraph":
2403  $sname = $res->nodeset[$i]->get_attribute("Characteristic");
2404  $stype = "text_block";
2405  $template = 0;
2406  break;
2407 
2408  case "Section":
2409  $sname = $res->nodeset[$i]->get_attribute("Characteristic");
2410  $stype = "section";
2411  $template = 0;
2412  break;
2413 
2414  case "MediaAlias":
2415  $sname = $res->nodeset[$i]->get_attribute("Class");
2416  $stype = "media_cont";
2417  $template = 0;
2418  break;
2419 
2420  case "FileItem":
2421  $sname = $res->nodeset[$i]->get_attribute("Class");
2422  $stype = "flist_li";
2423  $template = 0;
2424  break;
2425 
2426  case "Table":
2427  $sname = $res->nodeset[$i]->get_attribute("Template");
2428  if ($sname == "")
2429  {
2430  $sname = $res->nodeset[$i]->get_attribute("Class");
2431  $stype = "table";
2432  $template = 0;
2433  }
2434  else
2435  {
2436  $stype = "table";
2437  $template = 1;
2438  }
2439  break;
2440 
2441  case "TableData":
2442  $sname = $res->nodeset[$i]->get_attribute("Class");
2443  $stype = "table_cell";
2444  $template = 0;
2445  break;
2446 
2447  case "Tabs":
2448  $sname = $res->nodeset[$i]->get_attribute("Template");
2449  if ($sname != "")
2450  {
2451  if ($res->nodeset[$i]->get_attribute("Type") == "HorizontalAccordion")
2452  {
2453  $stype = "haccordion";
2454  }
2455  if ($res->nodeset[$i]->get_attribute("Type") == "VerticalAccordion")
2456  {
2457  $stype = "vaccordion";
2458  }
2459  }
2460  $template = 1;
2461  break;
2462 
2463  case "List":
2464  $sname = $res->nodeset[$i]->get_attribute("Class");
2465  if ($res->nodeset[$i]->get_attribute("Type") == "Ordered")
2466  {
2467  $stype = "list_o";
2468  }
2469  else
2470  {
2471  $stype = "list_u";
2472  }
2473  $template = 0;
2474  break;
2475  }
2476  if ($sname != "" && $stype != "")
2477  {
2478  $usages[$sname.":".$stype.":".$template] = array("sname" => $sname,
2479  "stype" => $stype, "template" => $template);
2480  }
2481  }
2482 
2483  $ilDB->manipulate("DELETE FROM page_style_usage WHERE ".
2484  " page_id = ".$ilDB->quote($this->getId(), "integer").
2485  " AND page_type = ".$ilDB->quote($this->getParentType(), "text").
2486  " AND page_nr = ".$ilDB->quote($a_old_nr, "integer")
2487  );
2488 
2489  foreach ($usages as $u)
2490  {
2491  $ilDB->manipulate("INSERT INTO page_style_usage ".
2492  "(page_id, page_type, page_nr, template, stype, sname) VALUES (".
2493  $ilDB->quote($this->getId(), "integer").",".
2494  $ilDB->quote($this->getParentType(), "text").",".
2495  $ilDB->quote($a_old_nr, "integer").",".
2496  $ilDB->quote($u["template"], "integer").",".
2497  $ilDB->quote($u["stype"], "text").",".
2498  $ilDB->quote($u["sname"], "text").
2499  ")");
2500  }
2501  }
2502 
2508  {
2509  include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
2510  include_once("./Modules/File/classes/class.ilObjFile.php");
2512  $this->getId());
2514  $this->getId());
2515  $objs = array_merge($mobs, $files);
2516  return ilObject::_getLastUpdateOfObjects($objs);
2517  }
2518 
2524  function saveInternalLinks($a_xml)
2525  {
2526 //echo "<br>PageObject::saveInternalLinks[".$this->getId()."]";
2527  $doc = domxml_open_mem($a_xml);
2528 
2529 
2530  include_once("./Services/COPage/classes/class.ilInternalLink.php");
2532 
2533  // get all internal links
2534  $xpc = xpath_new_context($doc);
2535  $path = "//IntLink";
2536  $res =& xpath_eval($xpc, $path);
2537  for ($i=0; $i < count($res->nodeset); $i++)
2538  {
2539  $link_type = $res->nodeset[$i]->get_attribute("Type");
2540 
2541  switch ($link_type)
2542  {
2543  case "StructureObject":
2544  $t_type = "st";
2545  break;
2546 
2547  case "PageObject":
2548  $t_type = "pg";
2549  break;
2550 
2551  case "GlossaryItem":
2552  $t_type = "git";
2553  break;
2554 
2555  case "MediaObject":
2556  $t_type = "mob";
2557  break;
2558 
2559  case "RepositoryItem":
2560  $t_type = "obj";
2561  break;
2562  }
2563 
2564  $target = $res->nodeset[$i]->get_attribute("Target");
2565  $target_arr = explode("_", $target);
2566  $t_id = $target_arr[count($target_arr) - 1];
2567 
2568  // link to other internal object
2569  if (is_int(strpos($target, "__")))
2570  {
2571  $t_inst = 0;
2572  }
2573  else // link to unresolved object in other installation
2574  {
2575  $t_inst = $target_arr[1];
2576  }
2577 
2578  if ($t_id > 0)
2579  {
2580  ilInternalLink::_saveLink($this->getParentType().":pg", $this->getId(), $t_type,
2581  $t_id, $t_inst);
2582  }
2583  }
2584 
2585  }
2586 
2592  function saveAnchors($a_xml)
2593  {
2594  $doc = domxml_open_mem($a_xml);
2595 
2596  ilPageObject::_deleteAnchors($this->getParentType(), $this->getId());
2597 
2598  // get all anchors
2599  $xpc = xpath_new_context($doc);
2600  $path = "//Anchor";
2601  $res =& xpath_eval($xpc, $path);
2602  $saved = array();
2603  for ($i=0; $i < count($res->nodeset); $i++)
2604  {
2605  $name = $res->nodeset[$i]->get_attribute("Name");
2606  if (trim($name) != "" && !in_array($name, $saved))
2607  {
2608  ilPageObject::_saveAnchor($this->getParentType(), $this->getId(), $name);
2609  $saved[] = $name;
2610  }
2611  }
2612 
2613  }
2614 
2618  static function _deleteAnchors($a_parent_type, $a_page_id)
2619  {
2620  global $ilDB;
2621 
2622  $st = $ilDB->prepareManip("DELETE FROM page_anchor WHERE page_parent_type = ? ".
2623  " AND page_id = ?", array("text", "integer"));
2624  $ilDB->execute($st, array($a_parent_type, $a_page_id));
2625  }
2626 
2630  static function _saveAnchor($a_parent_type, $a_page_id, $a_anchor_name)
2631  {
2632  global $ilDB;
2633 
2634  $st = $ilDB->prepareManip("INSERT INTO page_anchor (page_parent_type, page_id, anchor_name) ".
2635  " VALUES (?,?,?) ", array("text", "integer", "text"));
2636  $ilDB->execute($st, array($a_parent_type, $a_page_id, $a_anchor_name));
2637  }
2638 
2642  static function _readAnchors($a_parent_type, $a_page_id)
2643  {
2644  global $ilDB;
2645 
2646  $st = $ilDB->prepare("SELECT * FROM page_anchor WHERE page_parent_type = ? ".
2647  " AND page_id = ?", array("text", "integer"));
2648  $set = $ilDB->execute($st, array($a_parent_type, $a_page_id));
2649  $anchors = array();
2650  while ($rec = $ilDB->fetchAssoc($set))
2651  {
2652  $anchors[] = $rec["anchor_name"];
2653  }
2654  return $anchors;
2655  }
2656 
2660  function create()
2661  {
2662  $this->createFromXML();
2663  }
2664 
2672  function deleteContent($a_hid, $a_update = true, $a_pcid = "")
2673  {
2674  $curr_node =& $this->getContentNode($a_hid, $a_pcid);
2675  $curr_node->unlink_node($curr_node);
2676  if ($a_update)
2677  {
2678  return $this->update();
2679  }
2680  }
2681 
2682 
2690  function deleteContents($a_hids, $a_update = true)
2691  {
2692  if (!is_array($a_hids))
2693  {
2694  return;
2695  }
2696  foreach($a_hids as $a_hid)
2697  {
2698  $a_hid = explode(":", $a_hid);
2699 //echo "-".$a_hid[0]."-".$a_hid[1]."-";
2700  $curr_node =& $this->getContentNode($a_hid[0], $a_hid[1]);
2701  if (is_object($curr_node))
2702  {
2703  $parent_node = $curr_node->parent_node();
2704  if ($parent_node->node_name() != "TableRow")
2705  {
2706  $curr_node->unlink_node($curr_node);
2707  }
2708  }
2709  }
2710  if ($a_update)
2711  {
2712  return $this->update();
2713  }
2714  }
2715 
2721  function cutContents($a_hids)
2722  {
2723  $this->copyContents($a_hids);
2724  return $this->deleteContents($a_hids);
2725  }
2726 
2732  function copyContents($a_hids)
2733  {
2734  global $ilUser;
2735 //var_dump($a_hids);
2736  if (!is_array($a_hids))
2737  {
2738  return;
2739  }
2740 
2741  $time = date("Y-m-d H:i:s", time());
2742 
2743  $hier_ids = array();
2744  $skip = array();
2745  foreach($a_hids as $a_hid)
2746  {
2747  if ($a_hid == "")
2748  {
2749  continue;
2750  }
2751  $a_hid = explode(":", $a_hid);
2752 
2753  // check, whether new hid is child of existing one or vice versa
2754  reset($hier_ids);
2755  foreach($hier_ids as $h)
2756  {
2757  if($h."_" == substr($a_hid[0], 0, strlen($h) + 1))
2758  {
2759  $skip[] = $a_hid[0];
2760  }
2761  if($a_hid[0]."_" == substr($h, 0, strlen($a_hid[0]) + 1))
2762  {
2763  $skip[] = $h;
2764  }
2765  }
2766  $pc_id[$a_hid[0]] = $a_hid[1];
2767  if ($a_hid[0] != "")
2768  {
2769  $hier_ids[$a_hid[0]] = $a_hid[0];
2770  }
2771  }
2772  foreach ($skip as $s)
2773  {
2774  unset($hier_ids[$s]);
2775  }
2776  include_once("./Services/COPage/classes/class.ilPageContent.php");
2777  $hier_ids = ilPageContent::sortHierIds($hier_ids);
2778  $nr = 1;
2779  foreach($hier_ids as $hid)
2780  {
2781  $curr_node = $this->getContentNode($hid, $pc_id[$hid]);
2782  if (is_object($curr_node))
2783  {
2784  if ($curr_node->node_name() == "PageContent")
2785  {
2786  $content = $this->dom->dump_node($curr_node);
2787  // remove pc and hier ids
2788  $content = eregi_replace("PCID=\"[a-z0-9]*\"","",$content);
2789  $content = eregi_replace("HierId=\"[a-z0-9_]*\"","",$content);
2790 
2791  $ilUser->addToPCClipboard($content, $time, $nr);
2792  $nr++;
2793  }
2794  }
2795  }
2796  include_once("./Modules/LearningModule/classes/class.ilEditClipboard.php");
2798  }
2799 
2803  function pasteContents($a_hier_id)
2804  {
2805  global $ilUser;
2806 
2807  $a_hid = explode(":", $a_hier_id);
2808  $content = $ilUser->getPCClipboardContent();
2809 
2810  // we insert from last to first, because we insert all at the
2811  // same hier_id
2812  for ($i = count($content) - 1; $i >= 0; $i--)
2813  {
2814 
2815  $c = $content[$i];
2816  $temp_dom = domxml_open_mem('<?xml version="1.0" encoding="UTF-8"?>'.$c,
2818  if(empty($error))
2819  {
2820  $this->newQuestionCopies($temp_dom);
2821  $xpc = xpath_new_context($temp_dom);
2822  $path = "//PageContent";
2823  $res = xpath_eval($xpc, $path);
2824  if (count($res->nodeset) > 0)
2825  {
2826  $new_pc_node = $res->nodeset[0];
2827  $cloned_pc_node = $new_pc_node->clone_node (true);
2828  $cloned_pc_node->unlink_node ($cloned_pc_node);
2829  $this->insertContentNode ($cloned_pc_node, $a_hid[0],
2830  IL_INSERT_AFTER, $a_hid[1]);
2831  }
2832  }
2833  else
2834  {
2835 //var_dump($error);
2836  }
2837  }
2838  $e = $this->update();
2839 //var_dump($e);
2840  }
2841 
2846  function switchEnableMultiple($a_hids, $a_update = true)
2847  {
2848  if (!is_array($a_hids))
2849  {
2850  return;
2851  }
2852  $obj = & $this->content_obj;
2853 
2854  foreach($a_hids as $a_hid)
2855  {
2856  $a_hid = explode(":", $a_hid);
2857 //echo "-".$a_hid[0]."-".$a_hid[1]."-";
2858  $curr_node =& $this->getContentNode($a_hid[0], $a_hid[1]);
2859  if (is_object($curr_node))
2860  {
2861  if ($curr_node->node_name() == "PageContent")
2862  {
2863  $cont_obj =& $this->getContentObject($a_hid[0], $a_hid[1]);
2864  if ($cont_obj->isEnabled ())
2865  $cont_obj->disable ();
2866  else
2867  $cont_obj->enable ();
2868  }
2869  }
2870  }
2871 
2872  if ($a_update)
2873  {
2874  return $this->update();
2875  }
2876  }
2877 
2878 
2886  function deleteContentFromHierId($a_hid, $a_update = true)
2887  {
2888  $hier_ids = $this->getHierIds();
2889 
2890  // iterate all hierarchical ids
2891  foreach ($hier_ids as $hier_id)
2892  {
2893  // delete top level nodes only
2894  if (!is_int(strpos($hier_id, "_")))
2895  {
2896  if ($hier_id != "pg" && $hier_id >= $a_hid)
2897  {
2898  $curr_node =& $this->getContentNode($hier_id);
2899  $curr_node->unlink_node($curr_node);
2900  }
2901  }
2902  }
2903  if ($a_update)
2904  {
2905  return $this->update();
2906  }
2907  }
2908 
2916  function deleteContentBeforeHierId($a_hid, $a_update = true)
2917  {
2918  $hier_ids = $this->getHierIds();
2919 
2920  // iterate all hierarchical ids
2921  foreach ($hier_ids as $hier_id)
2922  {
2923  // delete top level nodes only
2924  if (!is_int(strpos($hier_id, "_")))
2925  {
2926  if ($hier_id != "pg" && $hier_id < $a_hid)
2927  {
2928  $curr_node =& $this->getContentNode($hier_id);
2929  $curr_node->unlink_node($curr_node);
2930  }
2931  }
2932  }
2933  if ($a_update)
2934  {
2935  return $this->update();
2936  }
2937  }
2938 
2939 
2947  function _moveContentAfterHierId(&$a_source_page, &$a_target_page, $a_hid)
2948  {
2949  $hier_ids = $a_source_page->getHierIds();
2950 
2951  $copy_ids = array();
2952 
2953  // iterate all hierarchical ids
2954  foreach ($hier_ids as $hier_id)
2955  {
2956  // move top level nodes only
2957  if (!is_int(strpos($hier_id, "_")))
2958  {
2959  if ($hier_id != "pg" && $hier_id >= $a_hid)
2960  {
2961  $copy_ids[] = $hier_id;
2962  }
2963  }
2964  }
2965  asort($copy_ids);
2966 
2967  $parent_node =& $a_target_page->getContentNode("pg");
2968  $target_dom =& $a_target_page->getDom();
2969  $parent_childs =& $parent_node->child_nodes();
2970  $cnt_parent_childs = count($parent_childs);
2971 //echo "-$cnt_parent_childs-";
2972  $first_child =& $parent_childs[0];
2973  foreach($copy_ids as $copy_id)
2974  {
2975  $source_node =& $a_source_page->getContentNode($copy_id);
2976 
2977  $new_node =& $source_node->clone_node(true);
2978  $new_node->unlink_node($new_node);
2979 
2980  $source_node->unlink_node($source_node);
2981 
2982  if($cnt_parent_childs == 0)
2983  {
2984  $new_node =& $parent_node->append_child($new_node);
2985  }
2986  else
2987  {
2988  //$target_dom->import_node($new_node);
2989  $new_node =& $first_child->insert_before($new_node, $first_child);
2990  }
2991  $parent_childs =& $parent_node->child_nodes();
2992 
2993  //$cnt_parent_childs++;
2994  }
2995 
2996  $a_target_page->update();
2997  $a_source_page->update();
2998 
2999  }
3000 
3004  function insertContent(&$a_cont_obj, $a_pos, $a_mode = IL_INSERT_AFTER, $a_pcid = "")
3005  {
3006  // move mode into container elements is always INSERT_CHILD
3007  $curr_node = $this->getContentNode($a_pos, $a_pcid);
3008  $curr_name = $curr_node->node_name();
3009  if (($curr_name == "TableData") || ($curr_name == "PageObject") ||
3010  ($curr_name == "ListItem") || ($curr_name == "Section")
3011  || ($curr_name == "Tab"))
3012  {
3013  $a_mode = IL_INSERT_CHILD;
3014  }
3015 
3016  $hid = $curr_node->get_attribute("HierId");
3017  if ($hid != "")
3018  {
3019 //echo "-".$a_pos."-".$hid."-";
3020  $a_pos = $hid;
3021  }
3022 
3023  if($a_mode != IL_INSERT_CHILD) // determine parent hierarchical id
3024  { // of sibling at $a_pos
3025  $pos = explode("_", $a_pos);
3026  $target_pos = array_pop($pos);
3027  $parent_pos = implode($pos, "_");
3028  }
3029  else // if we should insert a child, $a_pos is alreade the hierarchical id
3030  { // of the parent node
3031  $parent_pos = $a_pos;
3032  }
3033 
3034  // get the parent node
3035  if($parent_pos != "")
3036  {
3037  $parent_node =& $this->getContentNode($parent_pos);
3038  }
3039  else
3040  {
3041  $parent_node =& $this->getNode();
3042  }
3043 
3044  // count the parent children
3045  $parent_childs =& $parent_node->child_nodes();
3046  $cnt_parent_childs = count($parent_childs);
3047 //echo "ZZ$a_mode";
3048  switch ($a_mode)
3049  {
3050  // insert new node after sibling at $a_pos
3051  case IL_INSERT_AFTER:
3052  $new_node =& $a_cont_obj->getNode();
3053  //$a_pos = ilPageContent::incEdId($a_pos);
3054  //$curr_node =& $this->getContentNode($a_pos);
3055 //echo "behind $a_pos:";
3056  if($succ_node =& $curr_node->next_sibling())
3057  {
3058  $new_node =& $succ_node->insert_before($new_node, $succ_node);
3059  }
3060  else
3061  {
3062 //echo "movin doin append_child";
3063  $new_node =& $parent_node->append_child($new_node);
3064  }
3065  $a_cont_obj->setNode($new_node);
3066  break;
3067 
3068  case IL_INSERT_BEFORE:
3069 //echo "INSERT_BEF";
3070  $new_node =& $a_cont_obj->getNode();
3071  $succ_node =& $this->getContentNode($a_pos);
3072  $new_node =& $succ_node->insert_before($new_node, $succ_node);
3073  $a_cont_obj->setNode($new_node);
3074  break;
3075 
3076  // insert new node as first child of parent $a_pos (= $a_parent)
3077  case IL_INSERT_CHILD:
3078 //echo "insert as child:parent_childs:$cnt_parent_childs:<br>";
3079  $new_node =& $a_cont_obj->getNode();
3080  if($cnt_parent_childs == 0)
3081  {
3082  $new_node =& $parent_node->append_child($new_node);
3083  }
3084  else
3085  {
3086  $new_node =& $parent_childs[0]->insert_before($new_node, $parent_childs[0]);
3087  }
3088  $a_cont_obj->setNode($new_node);
3089 //echo "PP";
3090  break;
3091  }
3092 
3093  //check for PlaceHolder to remove in EditMode-keep in Layout Mode
3094  if (!$this->getLayoutMode()) {
3095  $sub_nodes = $curr_node->child_nodes() ;
3096  foreach ( $sub_nodes as $sub_node ) {
3097  if ($sub_node->node_name() == "PlaceHolder") {
3098  $curr_node->unlink_node();
3099  }
3100  }
3101  }
3102  }
3103 
3107  function insertContentNode(&$a_cont_node, $a_pos, $a_mode = IL_INSERT_AFTER, $a_pcid = "")
3108  {
3109  // move mode into container elements is always INSERT_CHILD
3110  $curr_node = $this->getContentNode($a_pos, $a_pcid);
3111  $curr_name = $curr_node->node_name();
3112  if (($curr_name == "TableData") || ($curr_name == "PageObject") ||
3113  ($curr_name == "ListItem") || ($curr_name == "Section")
3114  || ($curr_name == "Tab"))
3115  {
3116  $a_mode = IL_INSERT_CHILD;
3117  }
3118 
3119  $hid = $curr_node->get_attribute("HierId");
3120  if ($hid != "")
3121  {
3122  $a_pos = $hid;
3123  }
3124 
3125  if($a_mode != IL_INSERT_CHILD) // determine parent hierarchical id
3126  { // of sibling at $a_pos
3127  $pos = explode("_", $a_pos);
3128  $target_pos = array_pop($pos);
3129  $parent_pos = implode($pos, "_");
3130  }
3131  else // if we should insert a child, $a_pos is alreade the hierarchical id
3132  { // of the parent node
3133  $parent_pos = $a_pos;
3134  }
3135 
3136  // get the parent node
3137  if($parent_pos != "")
3138  {
3139  $parent_node =& $this->getContentNode($parent_pos);
3140  }
3141  else
3142  {
3143  $parent_node =& $this->getNode();
3144  }
3145 
3146  // count the parent children
3147  $parent_childs =& $parent_node->child_nodes();
3148  $cnt_parent_childs = count($parent_childs);
3149 
3150  switch ($a_mode)
3151  {
3152  // insert new node after sibling at $a_pos
3153  case IL_INSERT_AFTER:
3154  //$new_node =& $a_cont_obj->getNode();
3155  if($succ_node = $curr_node->next_sibling())
3156  {
3157  $a_cont_node = $succ_node->insert_before($a_cont_node, $succ_node);
3158  }
3159  else
3160  {
3161  $a_cont_node = $parent_node->append_child($a_cont_node);
3162  }
3163  //$a_cont_obj->setNode($new_node);
3164  break;
3165 
3166  case IL_INSERT_BEFORE:
3167  //$new_node =& $a_cont_obj->getNode();
3168  $succ_node = $this->getContentNode($a_pos);
3169  $a_cont_node = $succ_node->insert_before($a_cont_node, $succ_node);
3170  //$a_cont_obj->setNode($new_node);
3171  break;
3172 
3173  // insert new node as first child of parent $a_pos (= $a_parent)
3174  case IL_INSERT_CHILD:
3175  //$new_node =& $a_cont_obj->getNode();
3176  if($cnt_parent_childs == 0)
3177  {
3178  $a_cont_node = $parent_node->append_child($a_cont_node);
3179  }
3180  else
3181  {
3182  $a_cont_node = $parent_childs[0]->insert_before($a_cont_node, $parent_childs[0]);
3183  }
3184  //$a_cont_obj->setNode($new_node);
3185  break;
3186  }
3187  }
3188 
3193  function moveContentBefore($a_source, $a_target, $a_spcid = "", $a_tpcid = "")
3194  {
3195  if($a_source == $a_target)
3196  {
3197  return;
3198  }
3199 
3200  // clone the node
3201  $content =& $this->getContentObject($a_source, $a_spcid);
3202  $source_node =& $content->getNode();
3203  $clone_node =& $source_node->clone_node(true);
3204 
3205  // delete source node
3206  $this->deleteContent($a_source, false, $a_spcid);
3207 
3208  // insert cloned node at target
3209  $content->setNode($clone_node);
3210  $this->insertContent($content, $a_target, IL_INSERT_BEFORE, $a_tpcid);
3211  return $this->update();
3212 
3213  }
3214 
3219  function moveContentAfter($a_source, $a_target, $a_spcid = "", $a_tpcid = "")
3220  {
3221  if($a_source == $a_target)
3222  {
3223  return;
3224  }
3225 
3226  // clone the node
3227  $content =& $this->getContentObject($a_source, $a_spcid);
3228  $source_node =& $content->getNode();
3229  $clone_node =& $source_node->clone_node(true);
3230 
3231  // delete source node
3232  $this->deleteContent($a_source, false, $a_spcid);
3233 
3234  // insert cloned node at target
3235  $content->setNode($clone_node);
3236  $this->insertContent($content, $a_target, IL_INSERT_AFTER, $a_tpcid);
3237  return $this->update();
3238  }
3239 
3243  function bbCode2XML(&$a_content)
3244  {
3245  $a_content = eregi_replace("\[com\]","<Comment>",$a_content);
3246  $a_content = eregi_replace("\[\/com\]","</Comment>",$a_content);
3247  $a_content = eregi_replace("\[emp]","<Emph>",$a_content);
3248  $a_content = eregi_replace("\[\/emp\]","</Emph>",$a_content);
3249  $a_content = eregi_replace("\[str]","<Strong>",$a_content);
3250  $a_content = eregi_replace("\[\/str\]","</Strong>",$a_content);
3251  }
3252 
3257  function insertInstIntoIDs($a_inst, $a_res_ref_to_obj_id = true)
3258  {
3259  // insert inst id into internal links
3260  $xpc = xpath_new_context($this->dom);
3261  $path = "//IntLink";
3262  $res =& xpath_eval($xpc, $path);
3263  for($i = 0; $i < count($res->nodeset); $i++)
3264  {
3265  $target = $res->nodeset[$i]->get_attribute("Target");
3266  $type = $res->nodeset[$i]->get_attribute("Type");
3267 
3268  if (substr($target, 0, 4) == "il__")
3269  {
3270  $id = substr($target, 4, strlen($target) - 4);
3271 
3272  // convert repository links obj_<ref_id> to <type>_<obj_id>
3273  if ($a_res_ref_to_obj_id && $type == "RepositoryItem")
3274  {
3275  $id_arr = explode("_", $id);
3276  $obj_id = ilObject::_lookupObjId($id_arr[1]);
3277  $otype = ilObject::_lookupType($obj_id);
3278  if ($obj_id > 0)
3279  {
3280  $id = $otype."_".$obj_id;
3281  }
3282  }
3283  $new_target = "il_".$a_inst."_".$id;
3284  $res->nodeset[$i]->set_attribute("Target", $new_target);
3285  }
3286  }
3287  unset($xpc);
3288 
3289  // insert inst id into media aliases
3290  $xpc = xpath_new_context($this->dom);
3291  $path = "//MediaAlias";
3292  $res =& xpath_eval($xpc, $path);
3293  for($i = 0; $i < count($res->nodeset); $i++)
3294  {
3295  $origin_id = $res->nodeset[$i]->get_attribute("OriginId");
3296  if (substr($origin_id, 0, 4) == "il__")
3297  {
3298  $new_id = "il_".$a_inst."_".substr($origin_id, 4, strlen($origin_id) - 4);
3299  $res->nodeset[$i]->set_attribute("OriginId", $new_id);
3300  }
3301  }
3302  unset($xpc);
3303 
3304  // insert inst id file item identifier entries
3305  $xpc = xpath_new_context($this->dom);
3306  $path = "//FileItem/Identifier";
3307  $res =& xpath_eval($xpc, $path);
3308  for($i = 0; $i < count($res->nodeset); $i++)
3309  {
3310  $origin_id = $res->nodeset[$i]->get_attribute("Entry");
3311  if (substr($origin_id, 0, 4) == "il__")
3312  {
3313  $new_id = "il_".$a_inst."_".substr($origin_id, 4, strlen($origin_id) - 4);
3314  $res->nodeset[$i]->set_attribute("Entry", $new_id);
3315  }
3316  }
3317  unset($xpc);
3318 
3319  // insert inst id into
3320  $xpc = xpath_new_context($this->dom);
3321  $path = "//Question";
3322  $res =& xpath_eval($xpc, $path);
3323  for($i = 0; $i < count($res->nodeset); $i++)
3324  {
3325  $qref = $res->nodeset[$i]->get_attribute("QRef");
3326 //echo "<br>setted:".$qref;
3327  if (substr($qref, 0, 4) == "il__")
3328  {
3329  $new_id = "il_".$a_inst."_".substr($qref, 4, strlen($qref) - 4);
3330 //echo "<br>setting:".$new_id;
3331  $res->nodeset[$i]->set_attribute("QRef", $new_id);
3332  }
3333  }
3334  unset($xpc);
3335 
3336  }
3337 
3342  function highlightText($a_text, $proglang, $autoindent)
3343  {
3344 
3345  if (!$this->hasHighlighter($proglang)) {
3346  $proglang="plain";
3347  }
3348 
3349  require_once("./Services/COPage/syntax_highlight/php/HFile/HFile_".$proglang.".php");
3350  $classname = "HFile_$proglang";
3351  $h_instance = new $classname();
3352  if ($autoindent == "n") {
3353  $h_instance ->notrim = 1;
3354  $h_instance ->indent = array ("");
3355  $h_instance ->unindent = array ("");
3356  }
3357 
3358  $highlighter = new Core($h_instance, new Output_css());
3359  $a_text = $highlighter->highlight_text(html_entity_decode($a_text));
3360 
3361  return $a_text;
3362  }
3363 
3364  function hasHighlighter ($hfile_ext) {
3365  return file_exists ("Services/COPage/syntax_highlight/php/HFile/HFile_".$hfile_ext.".php");
3366  }
3367 
3373  function insertSourceCodeParagraphs($a_output, $outputmode = "presentation")
3374  {
3375  $xpc = xpath_new_context($this->dom);
3376  $path = "//Paragraph"; //"[@Characteristic = 'Code']";
3377  $res = & xpath_eval($xpc, $path);
3378  for($i = 0; $i < count($res->nodeset); $i++)
3379  {
3380  $context_node = $res->nodeset[$i];
3381  $char = $context_node->get_attribute('Characteristic');
3382 
3383  if ($char != "Code")
3384  continue;
3385 
3386  $n = $context_node->parent_node();
3387  $char = $context_node->get_attribute('Characteristic');
3388  $subchar = $context_node->get_attribute('SubCharacteristic');
3389  $showlinenumbers = $context_node->get_attribute('ShowLineNumbers');
3390  $downloadtitle = $context_node->get_attribute('DownloadTitle');
3391  $autoindent = $context_node->get_attribute('AutoIndent');
3392 
3393  $content = "";
3394 
3395  // get XML Content
3396  $childs = $context_node->child_nodes();
3397 
3398  for($j=0; $j<count($childs); $j++)
3399  {
3400  $content .= $this->dom->dump_node($childs[$j]);
3401  }
3402 
3403  while ($context_node->has_child_nodes ())
3404  {
3405  $node_del = $context_node->first_child ();
3406  $context_node->remove_child ($node_del);
3407  }
3408 
3409  $content = str_replace("<br />", "<br/>", utf8_decode($content) );
3410  $content = str_replace("<br/>", "\n", $content);
3411  $rownums = count(split ("\n",$content));
3412 
3413  $plain_content = html_entity_decode($content);
3414  $plain_content = preg_replace ("/\&#x([1-9a-f]{2});?/ise","chr (base_convert (\\1, 16, 10))",$plain_content);
3415  $plain_content = preg_replace ("/\&#(\d+);?/ise","chr (\\1)",$plain_content);
3416  $content = utf8_encode($this->highlightText($plain_content, $subchar, $autoindent));
3417 
3418  $content = str_replace("&amp;lt;", "&lt;", $content);
3419  $content = str_replace("&amp;gt;", "&gt;", $content);
3420 // $content = str_replace("&", "&amp;", $content);
3421 //var_dump($content);
3422  $rows = "<tr valign=\"top\">";
3423  $rownumbers = "";
3424  $linenumbers= "";
3425 
3426  //if we have to show line numbers
3427  if (strcmp($showlinenumbers,"y")==0)
3428  {
3429  $linenumbers = "<td nowrap=\"nowrap\" class=\"ilc_LineNumbers\" >";
3430  $linenumbers .= "<pre class=\"ilc_Code\">";
3431 
3432  for ($j=0; $j < $rownums; $j++)
3433  {
3434  $indentno = strlen($rownums) - strlen($j+1) + 2;
3435  $rownumeration = ($j+1);
3436  $linenumbers .= "<span class=\"ilc_LineNumber\">$rownumeration</span>";
3437  if ($j < $rownums-1)
3438  {
3439  $linenumbers .= "\n";
3440  }
3441  }
3442  $linenumbers .= "</pre>";
3443  $linenumbers .= "</td>";
3444  }
3445 
3446  $rows .= $linenumbers."<td class=\"ilc_Sourcecode\"><pre class=\"ilc_Code\">".$content."</pre></td>";
3447  $rows .= "</tr>";
3448 
3449  // fix for ie explorer which is not able to produce empty line feeds with <br /><br />;
3450  // workaround: add a space after each br.
3451  $newcontent = str_replace("\n", "<br/>",$rows);
3452  // fix for IE
3453  $newcontent = str_replace("<br/><br/>", "<br/> <br/>",$newcontent);
3454  // falls drei hintereinander...
3455  $newcontent = str_replace("<br/><br/>", "<br/> <br/>",$newcontent);
3456 
3457  // workaround for preventing template engine
3458  // from hiding paragraph text that is enclosed
3459  // in curly brackets (e.g. "{a}", see ilLMEditorGUI::executeCommand())
3460  $newcontent = str_replace("{", "&#123;", $newcontent);
3461  $newcontent = str_replace("}", "&#125;", $newcontent);
3462 
3463 //echo htmlentities($newcontent);
3464  $a_output = str_replace("[[[[[Code;".($i + 1)."]]]]]", $newcontent, $a_output);
3465 
3466  if ($outputmode != "presentation" && is_object($this->offline_handler)
3467  && trim($downloadtitle) != "")
3468  {
3469  // call code handler for offline versions
3470  $this->offline_handler->handleCodeParagraph ($this->id, $i + 1, $downloadtitle, $plain_content);
3471  }
3472  }
3473 
3474  return $a_output;
3475  }
3476 
3477 
3481  function checkPCIds()
3482  {
3483  $this->builddom();
3484  $mydom = $this->dom;
3485 
3486  $sep = $path = "";
3487  foreach ($this->id_elements as $el)
3488  {
3489  $path.= $sep."//".$el."[not(@PCID)]";
3490  $sep = " | ";
3491  }
3492 
3493  $xpc = xpath_new_context($mydom);
3494  $res = & xpath_eval($xpc, $path);
3495 
3496  if (count ($res->nodeset) > 0)
3497  {
3498  return false;
3499  }
3500  return true;
3501  }
3502 
3506  function insertPCIds()
3507  {
3508  $this->builddom();
3509  $mydom = $this->dom;
3510 
3511  $pcids = array();
3512 
3513  $sep = $path = "";
3514  foreach ($this->id_elements as $el)
3515  {
3516  $path.= $sep."//".$el."[@PCID]";
3517  $sep = " | ";
3518  }
3519 
3520  // get existing ids
3521  $xpc = xpath_new_context($mydom);
3522  $res = & xpath_eval($xpc, $path);
3523 
3524  for ($i = 0; $i < count ($res->nodeset); $i++)
3525  {
3526  $node = $res->nodeset[$i];
3527  $pcids[] = $node->get_attribute("PCID");
3528  }
3529 
3530  // add missing ones
3531  $sep = $path = "";
3532  foreach ($this->id_elements as $el)
3533  {
3534  $path.= $sep."//".$el."[not(@PCID)]";
3535  $sep = " | ";
3536  }
3537  $xpc = xpath_new_context($mydom);
3538  $res = & xpath_eval($xpc, $path);
3539 
3540  for ($i = 0; $i < count ($res->nodeset); $i++)
3541  {
3542  $node = $res->nodeset[$i];
3543  $id = ilUtil::randomHash(10, $pcids);
3544  $pcids[] = $id;
3545 //echo "setting-".$id."-";
3546  $res->nodeset[$i]->set_attribute("PCID", $id);
3547  }
3548  }
3549 
3554  {
3555  $this->builddom();
3556  $this->addHierIds();
3557  $mydom = $this->dom;
3558 
3559  // get existing ids
3560  $path = "//PageContent";
3561  $xpc = xpath_new_context($mydom);
3562  $res = & xpath_eval($xpc, $path);
3563 
3564  $hashes = array();
3565  require_once("./Services/COPage/classes/class.ilPCParagraph.php");
3566  for ($i = 0; $i < count ($res->nodeset); $i++)
3567  {
3568  $hier_id = $res->nodeset[$i]->get_attribute("HierId");
3569  $pc_id = $res->nodeset[$i]->get_attribute("PCID");
3570  $dump = $mydom->dump_node($res->nodeset[$i]);
3571  if (($hpos = strpos($dump, ' HierId="'.$hier_id.'"')) > 0)
3572  {
3573  $dump = substr($dump, 0, $hpos).
3574  substr($dump, $hpos + strlen(' HierId="'.$hier_id.'"'));
3575  }
3576 
3577  $childs = $res->nodeset[$i]->child_nodes();
3578  $content = "";
3579  if ($childs[0] && $childs[0]->node_name() == "Paragraph")
3580  {
3581  $content = $mydom->dump_node($childs[0]);
3582  $content = substr($content, strpos($content, ">") + 1,
3583  strrpos($content, "<") - (strpos($content, ">") + 1));
3584 //var_dump($content);
3585  $content = ilPCParagraph::xml2output($content);
3586 //var_dump($content);
3587  }
3588  //$hashes[$hier_id] =
3589  // array("PCID" => $pc_id, "hash" => md5($dump));
3590  $hashes[$pc_id] =
3591  array("hier_id" => $hier_id, "hash" => md5($dump), "content" => $content);
3592  }
3593 
3594  return $hashes;
3595  }
3596 
3600  function getQuestionIds()
3601  {
3602  $this->builddom();
3603  $mydom = $this->dom;
3604 
3605  // Get question IDs
3606  $path = "//Question";
3607  $xpc = xpath_new_context($mydom);
3608  $res = & xpath_eval($xpc, $path);
3609 
3610  $q_ids = array();
3611  include_once("./Services/COPage/classes/class.ilInternalLink.php");
3612  for ($i = 0; $i < count ($res->nodeset); $i++)
3613  {
3614  $qref = $res->nodeset[$i]->get_attribute("QRef");
3615 
3616  $inst_id = ilInternalLink::_extractInstOfTarget($qref);
3617  $obj_id = ilInternalLink::_extractObjIdOfTarget($qref);
3618 
3619  if (!($inst_id > 0))
3620  {
3621  if ($obj_id > 0)
3622  {
3623  $q_ids[] = $obj_id;
3624  }
3625  }
3626  }
3627 
3628  return $q_ids;
3629  }
3630 
3631  function send_paragraph ($par_id, $filename)
3632  {
3633  $this->builddom();
3634 
3635  $mydom = $this->dom;
3636 
3637  $xpc = xpath_new_context($mydom);
3638 
3639  //$path = "//PageContent[position () = $par_id]/Paragraph";
3640  //$path = "//Paragraph[$par_id]";
3641  $path = "/descendant::Paragraph[position() = $par_id]";
3642 
3643  $res = & xpath_eval($xpc, $path);
3644 
3645  if (count ($res->nodeset) != 1)
3646  die ("Should not happen");
3647 
3648  $context_node = $res->nodeset[0];
3649 
3650  // get plain text
3651 
3652  $childs = $context_node->child_nodes();
3653 
3654  for($j=0; $j<count($childs); $j++)
3655  {
3656  $content .= $mydom->dump_node($childs[$j]);
3657  }
3658 
3659  $content = str_replace("<br />", "\n", $content);
3660  $content = str_replace("<br/>", "\n", $content);
3661 
3662  $plain_content = html_entity_decode($content);
3663 
3664  ilUtil::deliverData($plain_content, $filename);
3665  /*
3666  $file_type = "application/octet-stream";
3667  header("Content-type: ".$file_type);
3668  header("Content-disposition: attachment; filename=\"$filename\"");
3669  echo $plain_content;*/
3670  exit();
3671  }
3672 
3676  function getFO()
3677  {
3678  $xml = $this->getXMLFromDom(false, true, true);
3679  $xsl = file_get_contents("./Services/COPage/xsl/page_fo.xsl");
3680  $args = array( '/_xml' => $xml, '/_xsl' => $xsl );
3681  $xh = xslt_create();
3682 
3683  $params = array ();
3684 
3685 
3686  $fo = xslt_process($xh,"arg:/_xml","arg:/_xsl",NULL,$args, $params);
3687  var_dump($fo);
3688  // do some replacements
3689  $fo = str_replace("\n", "", $fo);
3690  $fo = str_replace("<br/>", "<br>", $fo);
3691  $fo = str_replace("<br>", "\n", $fo);
3692 
3693  xslt_free($xh);
3694 
3695  //
3696  $fo = substr($fo, strpos($fo,">") + 1);
3697 //echo "<br><b>fo:</b><br>".htmlentities($fo); flush();
3698  return $fo;
3699  }
3700 
3701  function registerOfflineHandler ($handler) {
3702  $this->offline_handler = $handler;
3703  }
3704 
3708  function _lookupContainsDeactivatedElements($a_id, $a_parent_type)
3709  {
3710  global $ilDB;
3711 
3712  /*$query = "SELECT * FROM page_object WHERE page_id = ".
3713  $ilDB->quote($a_id)." AND ".
3714  " parent_type = ".$ilDB->quote($a_parent_type)." AND ".
3715  " content LIKE '% Enabled=\"False\"%'";*/
3716  $query = "SELECT * FROM page_object WHERE page_id = ".
3717  $ilDB->quote($a_id, "integer")." AND ".
3718  " parent_type = ".$ilDB->quote($a_parent_type, "text")." AND ".
3719  " inactive_elements = ".$ilDB->quote(1, "integer");
3720  $obj_set = $ilDB->query($query);
3721 
3722  if ($obj_rec = $obj_set->fetchRow(DB_FETCHMODE_ASSOC))
3723  {
3724  return true;
3725  }
3726 
3727  return false;
3728  }
3729 
3736  function containsDeactivatedElements($a_content)
3737  {
3738  if (strpos($a_content, " Enabled=\"False\""))
3739  {
3740  return true;
3741  }
3742  return false;
3743  }
3744 
3749  {
3750  global $ilDB;
3751 
3752  $h_query = "SELECT * FROM page_history ".
3753  " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
3754  " AND parent_type = ".$ilDB->quote($this->getParentType(), "text").
3755  " ORDER BY hdate DESC";
3756 
3757  $hset = $ilDB->query($h_query);
3758  $hentries = array();
3759 
3760  while ($hrec = $ilDB->fetchAssoc($hset))
3761  {
3762  $hrec["sortkey"] = (int) $hrec["nr"];
3763  $hrec["user"] = (int) $hrec["user_id"];
3764  $hentries[] = $hrec;
3765  }
3766 //var_dump($hentries);
3767  return $hentries;
3768  }
3769 
3773  function getHistoryEntry($a_old_nr)
3774  {
3775  global $ilDB;
3776 
3777  $res = $ilDB->queryF("SELECT * FROM page_history ".
3778  " WHERE page_id = %s ".
3779  " AND parent_type = %s ".
3780  " AND nr = %s",
3781  array("integer", "text", "integer"),
3782  array($this->getId(), $this->getParentType(), $a_old_nr));
3783  if ($hrec = $ilDB->fetchAssoc($res))
3784  {
3785  return $hrec;
3786  }
3787 
3788  return false;
3789  }
3790 
3791 
3798  function getHistoryInfo($a_nr)
3799  {
3800  global $ilDB;
3801 
3802  // determine previous entry
3803  $res = $ilDB->query("SELECT MAX(nr) mnr FROM page_history ".
3804  " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
3805  " AND parent_type = ".$ilDB->quote($this->getParentType(), "text").
3806  " AND nr < ".$ilDB->quote((int) $a_nr, "integer"));
3807  $row = $ilDB->fetchAssoc($res);
3808  if ($row["mnr"] > 0)
3809  {
3810  $res = $ilDB->query("SELECT * FROM page_history ".
3811  " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
3812  " AND parent_type = ".$ilDB->quote($this->getParentType(), "text").
3813  " AND nr = ".$ilDB->quote((int) $row["mnr"], "integer"));
3814  $row = $ilDB->fetchAssoc($res);
3815  $ret["previous"] = $row;
3816  }
3817 
3818  // determine next entry
3819  $res = $ilDB->query("SELECT MIN(nr) mnr FROM page_history ".
3820  " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
3821  " AND parent_type = ".$ilDB->quote($this->getParentType(), "text").
3822  " AND nr > ".$ilDB->quote((int) $a_nr, "integer"));
3823  $row = $ilDB->fetchAssoc($res);
3824  if ($row["mnr"] > 0)
3825  {
3826  $res = $ilDB->query("SELECT * FROM page_history ".
3827  " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
3828  " AND parent_type = ".$ilDB->quote($this->getParentType(), "text").
3829  " AND nr = ".$ilDB->quote((int) $row["mnr"], "integer"));
3830  $row = $ilDB->fetchAssoc($res);
3831  $ret["next"] = $row;
3832  }
3833 
3834  // current
3835  $res = $ilDB->query("SELECT * FROM page_history ".
3836  " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
3837  " AND parent_type = ".$ilDB->quote($this->getParentType(), "text").
3838  " AND nr = ".$ilDB->quote((int) $a_nr, "integer"));
3839  $row = $ilDB->fetchAssoc($res);
3840  $ret["current"] = $row;
3841 
3842  return $ret;
3843  }
3844 
3845  function addChangeDivClasses($a_hashes)
3846  {
3847  $xpc = xpath_new_context($this->dom);
3848  $path = "/*[1]";
3849  $res =& xpath_eval($xpc, $path);
3850  $rnode = $res->nodeset[0];
3851 
3852 //echo "A";
3853  foreach($a_hashes as $pc_id => $h)
3854  {
3855 //echo "B";
3856  if ($h["change"] != "")
3857  {
3858 //echo "<br>C-".$h["hier_id"]."-".$h["change"]."-";
3859  $dc_node = $this->dom->create_element("DivClass");
3860  $dc_node->set_attribute("HierId", $h["hier_id"]);
3861  $dc_node->set_attribute("Class", "ilEdit".$h["change"]);
3862  $dc_node = $rnode->append_child($dc_node);
3863  }
3864  }
3865  }
3866 
3873  function compareVersion($a_left, $a_right)
3874  {
3875  global $ilDB;
3876 
3877  // get page objects
3878  $l_page = new ilPageObject($this->getParentType(), $this->getId(), $a_left);
3879  $r_page = new ilPageObject($this->getParentType(), $this->getId(), $a_right);
3880 
3881  $l_hashes = $l_page->getPageContentsHashes();
3882  $r_hashes = $r_page->getPageContentsHashes();
3883 
3884  // determine all deleted and changed page elements
3885  foreach ($l_hashes as $pc_id => $h)
3886  {
3887  if (!isset($r_hashes[$pc_id]))
3888  {
3889  $l_hashes[$pc_id]["change"] = "Deleted";
3890  }
3891  else
3892  {
3893  if ($l_hashes[$pc_id]["hash"] != $r_hashes[$pc_id]["hash"])
3894  {
3895  $l_hashes[$pc_id]["change"] = "Modified";
3896  $r_hashes[$pc_id]["change"] = "Modified";
3897 
3898  include_once("./Services/COPage/mediawikidiff/class.WordLevelDiff.php");
3899  // if modified element is a paragraph, highlight changes
3900  if ($l_hashes[$pc_id]["content"] != "" &&
3901  $r_hashes[$pc_id]["content"] != "")
3902  {
3903  $new_left = str_replace("\n", "<br />", $l_hashes[$pc_id]["content"]);
3904  $new_right = str_replace("\n", "<br />", $r_hashes[$pc_id]["content"]);
3905  $wldiff = new WordLevelDiff(array($new_left),
3906  array($new_right));
3907  $new_left = $wldiff->orig();
3908  $new_right = $wldiff->closing();
3909  $l_page->setParagraphContent($l_hashes[$pc_id]["hier_id"], $new_left[0]);
3910  $r_page->setParagraphContent($l_hashes[$pc_id]["hier_id"], $new_right[0]);
3911  }
3912  }
3913  }
3914  }
3915 
3916  // determine all new paragraphs
3917  foreach ($r_hashes as $pc_id => $h)
3918  {
3919  if (!isset($l_hashes[$pc_id]))
3920  {
3921  $r_hashes[$pc_id]["change"] = "New";
3922  }
3923  }
3924 
3925  $l_page->addChangeDivClasses($l_hashes);
3926  $r_page->addChangeDivClasses($r_hashes);
3927 
3928  return array("l_page" => $l_page, "r_page" => $r_page,
3929  "l_changes" => $l_hashes, "r_changes" => $r_hashes);
3930  }
3931 
3935  function increaseViewCnt()
3936  {
3937  global $ilDB;
3938 
3939  $ilDB->manipulate("UPDATE page_object ".
3940  " SET view_cnt = view_cnt + 1 ".
3941  " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
3942  " AND parent_type = ".$ilDB->quote($this->getParentType(), "text"));
3943  //$ilDB->query($q);
3944  }
3945 
3953  static function getRecentChanges($a_parent_type, $a_parent_id, $a_period = 30)
3954  {
3955  global $ilDB;
3956 
3957  $page_changes = array();
3958  $limit_ts = date('Y-m-d H:i:s', time() - ($a_period * 24 * 60 * 60));
3959  $q = "SELECT * FROM page_object ".
3960  " WHERE parent_id = ".$ilDB->quote($a_parent_id, "integer").
3961  " AND parent_type = ".$ilDB->quote($a_parent_type, "text").
3962  " AND last_change >= ".$ilDB->quote($limit_ts, "timestamp");
3963  // " AND (TO_DAYS(now()) - TO_DAYS(last_change)) <= ".((int)$a_period);
3964  $set = $ilDB->query($q);
3965  while($page = $ilDB->fetchAssoc($set))
3966  {
3967  $page_changes[] = array("date" => $page["last_change"],
3968  "id" => $page["page_id"], "type" => "page",
3969  "user" => $page["last_change_user"]);
3970  }
3971 
3972  $and_str = "";
3973  if ($a_period > 0)
3974  {
3975  $limit_ts = date('Y-m-d H:i:s', time() - ($a_period * 24 * 60 * 60));
3976  $and_str = " AND hdate >= ".$ilDB->quote($limit_ts, "timestamp")." ";
3977  }
3978 
3979  $q = "SELECT * FROM page_history ".
3980  " WHERE parent_id = ".$ilDB->quote($a_parent_id, "integer").
3981  " AND parent_type = ".$ilDB->quote($a_parent_type, "text").
3982  $and_str;
3983  $set = $ilDB->query($q);
3984  while ($page = $ilDB->fetchAssoc($set))
3985  {
3986  $page_changes[] = array("date" => $page["hdate"],
3987  "id" => $page["page_id"], "type" => "hist", "nr" => $page["nr"],
3988  "user" => $page["user_id"]);
3989  }
3990 
3991  $page_changes = ilUtil::sortArray($page_changes, "date", "desc");
3992 
3993  return $page_changes;
3994  }
3995 
4003  static function getAllPages($a_parent_type, $a_parent_id)
4004  {
4005  global $ilDB;
4006 
4007  $page_changes = array();
4008 
4009  $q = "SELECT * FROM page_object ".
4010  " WHERE parent_id = ".$ilDB->quote($a_parent_id, "integer").
4011  " AND parent_type = ".$ilDB->quote($a_parent_type, "text");
4012  $set = $ilDB->query($q);
4013  $pages = array();
4014  while ($page = $ilDB->fetchAssoc($set))
4015  {
4016  $pages[$page["page_id"]] = array("date" => $page["last_change"],
4017  "id" => $page["page_id"], "user" => $page["last_change_user"]);
4018  }
4019 
4020  return $pages;
4021  }
4022 
4029  static function getNewPages($a_parent_type, $a_parent_id)
4030  {
4031  global $ilDB;
4032 
4033  $pages = array();
4034 
4035  $q = "SELECT * FROM page_object ".
4036  " WHERE parent_id = ".$ilDB->quote($a_parent_id, "integer").
4037  " AND parent_type = ".$ilDB->quote($a_parent_type, "text").
4038  " ORDER BY created DESC";
4039  $set = $ilDB->query($q);
4040  while($page = $ilDB->fetchAssoc($set))
4041  {
4042  if ($page["created"] != "")
4043  {
4044  $pages[] = array("created" => $page["created"],
4045  "id" => $page["page_id"],
4046  "user" => $page["create_user"],
4047  );
4048  }
4049  }
4050 
4051  return $pages;
4052  }
4053 
4060  static function getParentObjectContributors($a_parent_type, $a_parent_id)
4061  {
4062  global $ilDB;
4063 
4064  $contributors = array();
4065  $set = $ilDB->queryF("SELECT last_change_user FROM page_object ".
4066  " WHERE parent_id = %s AND parent_type = %s ".
4067  " AND last_change_user != %s",
4068  array("integer", "text", "integer"),
4069  array($a_parent_id, $a_parent_type, 0));
4070 
4071  while ($page = $ilDB->fetchAssoc($set))
4072  {
4073  $contributors[$page["last_change_user"]][$page["page_id"]] = 1;
4074  }
4075 
4076  $set = $ilDB->queryF("SELECT count(*) as cnt, page_id, user_id FROM page_history ".
4077  " WHERE parent_id = %s AND parent_type = %s AND user_id != %s ".
4078  " GROUP BY page_id, user_id ",
4079  array("integer", "text", "integer"),
4080  array($a_parent_id, $a_parent_type, 0));
4081  while ($hpage = $ilDB->fetchAssoc($set))
4082  {
4083  $contributors[$hpage["user_id"]][$hpage["page_id"]] =
4084  $contributors[$hpage["user_id"]][$hpage["page_id"]] + $hpage["cnt"];
4085  }
4086 
4087  $c = array();
4088  foreach ($contributors as $k => $co)
4089  {
4091  $c[] = array("user_id" => $k, "pages" => $co,
4092  "lastname" => $name["lastname"], "firstname" => $name["firstname"]);
4093  }
4094 
4095  return $c;
4096  }
4097 
4104  static function getPageContributors($a_parent_type, $a_page_id)
4105  {
4106  global $ilDB;
4107 
4108  $contributors = array();
4109  $set = $ilDB->queryF("SELECT last_change_user FROM page_object ".
4110  " WHERE page_id = %s AND parent_type = %s ".
4111  " AND last_change_user != %s",
4112  array("integer", "text", "integer"),
4113  array($a_page_id, $a_parent_type, 0));
4114 
4115  while ($page = $ilDB->fetchAssoc($set))
4116  {
4117  $contributors[$page["last_change_user"]] = 1;
4118  }
4119 
4120  $set = $ilDB->queryF("SELECT count(*) as cnt, page_id, user_id FROM page_history ".
4121  " WHERE page_id = %s AND parent_type = %s AND user_id != %s ".
4122  " GROUP BY user_id, page_id ",
4123  array("integer", "text", "integer"),
4124  array($a_page_id, $a_parent_type, 0));
4125  while ($hpage = $ilDB->fetchAssoc($set))
4126  {
4127  $contributors[$hpage["user_id"]] =
4128  $contributors[$hpage["user_id"]] + $hpage["cnt"];
4129  }
4130 
4131  $c = array();
4132  foreach ($contributors as $k => $co)
4133  {
4135  $c[] = array("user_id" => $k, "pages" => $co,
4136  "lastname" => $name["lastname"], "firstname" => $name["firstname"]);
4137  }
4138 
4139  return $c;
4140  }
4141 
4145  function writeRenderedContent($a_content, $a_md5)
4146  {
4147  global $ilDB;
4148 
4149  $ilDB->update("page_object", array(
4150  "rendered_content" => array("clob", $a_content),
4151  "render_md5" => array("text", $a_md5),
4152  "rendered_time" => array("timestamp", ilUtil::now())
4153  ), array(
4154  "page_id" => array("integer", $this->getId()),
4155  "parent_type" => array("text", $this->getParentType())
4156  ));
4157  /*$st = $ilDB->prepareManip("UPDATE page_object ".
4158  " SET rendered_content = ?, render_md5 = ?, rendered_time = now()".
4159  " WHERE page_id = ? AND parent_type = ?",
4160  array("text", "text", "integer", "text"));
4161  $r = $ilDB->execute($st,
4162  array($a_content, $a_md5, $this->getId(), $this->getParentType()));*/
4163  }
4164 
4172  static function getPagesWithLinks($a_parent_type, $a_parent_id)
4173  {
4174  global $ilDB;
4175 
4176  $page_changes = array();
4177 
4178  $q = "SELECT * FROM page_object ".
4179  " WHERE parent_id = ".$ilDB->quote($a_parent_id, "integer").
4180  " AND parent_type = ".$ilDB->quote($a_parent_type, "text").
4181  " AND int_links = ".$ilDB->quote(1, "integer");
4182  $set = $ilDB->query($q);
4183  $pages = array();
4184  while ($page = $ilDB->fetchAssoc($set))
4185  {
4186  $pages[$page["page_id"]] = array("date" => $page["last_change"],
4187  "id" => $page["page_id"], "user" => $page["last_change_user"]);
4188  }
4189 
4190  return $pages;
4191  }
4192 
4199  function containsIntLinks($a_content)
4200  {
4201  if (strpos($a_content, "IntLink"))
4202  {
4203  return true;
4204  }
4205  return false;
4206  }
4207 
4208 }
4209 ?>