ILIAS  Release_4_1_x_branch Revision 61804
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.ilPageObject.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (c) 1998-2009 ILIAS open source, Extended GPL, see docs/LICENSE */
3 
4 define("IL_INSERT_BEFORE", 0);
5 define("IL_INSERT_AFTER", 1);
6 define("IL_INSERT_CHILD", 2);
7 
8 define ("IL_CHAPTER_TITLE", "st_title");
9 define ("IL_PAGE_TITLE", "pg_title");
10 define ("IL_NO_HEADER", "none");
11 
27 {
28  static $exists = array();
29 
30  var $id;
31  var $ilias;
32  var $dom;
33  var $xml;
34  var $encoding;
35  var $node;
36  var $cur_dtd = "ilias_pg_4_1.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");
419  $start = new ilDateTime($this->getActivationStart(), IL_CAL_DATETIME);
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 
514  function _writeParentId($a_parent_type, $a_pg_id, $a_par_id)
515  {
516  global $ilDB;
517 
518  $st = $ilDB->manipulateF("UPDATE page_object SET parent_id = %s WHERE page_id = %s".
519  " AND parent_type = %s", array("integer", "integer", "text"),
520  array($a_par_id, $a_pg_id, $a_parent_type));
521  }
522 
528  function setActivationStart($a_activationstart)
529  {
530  $this->activationstart = $a_activationstart;
531  }
532 
539  {
540  return $this->activationstart;
541  }
542 
548  function setActivationEnd($a_activationend)
549  {
550  $this->activationend = $a_activationend;
551  }
552 
558  function getActivationEnd()
559  {
560  return $this->activationend;
561  }
562 
563  function &getContentObject($a_hier_id, $a_pc_id = "")
564  {
565 //echo ":".$a_hier_id.":";
566 //echo "Content:".htmlentities($this->getXMLFromDOM()).":<br>";
567 //echo "ilPageObject::getContentObject:hierid:".$a_hier_id.":<br>";
568  $cont_node =& $this->getContentNode($a_hier_id, $a_pc_id);
569 //echo "ilPageObject::getContentObject:nodename:".$cont_node->node_name().":<br>";
570  if (!is_object($cont_node))
571  {
572  return false;
573  }
574  switch($cont_node->node_name())
575  {
576  case "PageContent":
577  $child_node =& $cont_node->first_child();
578 //echo "<br>nodename:".$child_node->node_name();
579  switch($child_node->node_name())
580  {
581  case "Paragraph":
582  require_once("./Services/COPage/classes/class.ilPCParagraph.php");
583  $par =& new ilPCParagraph($this->dom);
584  $par->setNode($cont_node);
585  $par->setHierId($a_hier_id);
586  $par->setPcId($a_pc_id);
587  return $par;
588 
589  case "Table":
590  if ($child_node->get_attribute("DataTable") == "y")
591  {
592  require_once("./Services/COPage/classes/class.ilPCDataTable.php");
593  $tab =& new ilPCDataTable($this->dom);
594  $tab->setNode($cont_node);
595  $tab->setHierId($a_hier_id);
596  }
597  else
598  {
599  require_once("./Services/COPage/classes/class.ilPCTable.php");
600  $tab =& new ilPCTable($this->dom);
601  $tab->setNode($cont_node);
602  $tab->setHierId($a_hier_id);
603  }
604  $tab->setPcId($a_pc_id);
605  return $tab;
606 
607  case "MediaObject":
608 if ($_GET["pgEdMediaMode"] != "") {echo "ilPageObject::error media"; exit;}
609 
610  //require_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
611  require_once("./Services/COPage/classes/class.ilPCMediaObject.php");
612 
613  $mal_node =& $child_node->first_child();
614 //echo "ilPageObject::getContentObject:nodename:".$mal_node->node_name().":<br>";
615  $id_arr = explode("_", $mal_node->get_attribute("OriginId"));
616  $mob_id = $id_arr[count($id_arr) - 1];
617 
618  // allow deletion of non-existing media objects
619  if (!ilObject::_exists($mob_id) && in_array("delete", $_POST))
620  {
621  $mob_id = 0;
622  }
623 
624  //$mob =& new ilObjMediaObject($mob_id);
625  $mob = new ilPCMediaObject($this->dom);
626  $mob->readMediaObject($mob_id);
627 
628  //$mob->setDom($this->dom);
629  $mob->setNode($cont_node);
630  $mob->setHierId($a_hier_id);
631  $mob->setPcId($a_pc_id);
632  return $mob;
633 
634  case "List":
635  require_once("./Services/COPage/classes/class.ilPCList.php");
636  $list = new ilPCList($this->dom);
637  $list->setNode($cont_node);
638  $list->setHierId($a_hier_id);
639  $list->setPcId($a_pc_id);
640  return $list;
641 
642  case "FileList":
643  require_once("./Services/COPage/classes/class.ilPCFileList.php");
644  $file_list = new ilPCFileList($this->dom);
645  $file_list->setNode($cont_node);
646  $file_list->setHierId($a_hier_id);
647  $file_list->setPcId($a_pc_id);
648  return $file_list;
649 
650  // note: assessment handling is forwarded to assessment gui classes
651  case "Question":
652  require_once("./Services/COPage/classes/class.ilPCQuestion.php");
653  $pc_question = new ilPCQuestion($this->dom);
654  $pc_question->setNode($cont_node);
655  $pc_question->setHierId($a_hier_id);
656  $pc_question->setPcId($a_pc_id);
657  return $pc_question;
658 
659  case "Section":
660  require_once("./Services/COPage/classes/class.ilPCSection.php");
661  $sec = new ilPCSection($this->dom);
662  $sec->setNode($cont_node);
663  $sec->setHierId($a_hier_id);
664  $sec->setPcId($a_pc_id);
665  return $sec;
666 
667  case "Resources":
668  require_once("./Services/COPage/classes/class.ilPCResources.php");
669  $res = new ilPCResources($this->dom);
670  $res->setNode($cont_node);
671  $res->setHierId($a_hier_id);
672  $res->setPcId($a_pc_id);
673  return $res;
674 
675  case "Map":
676  require_once("./Services/COPage/classes/class.ilPCMap.php");
677  $map = new ilPCMap($this->dom);
678  $map->setNode($cont_node);
679  $map->setHierId($a_hier_id);
680  $map->setPcId($a_pc_id);
681  return $map;
682 
683  case "Tabs":
684  require_once("./Services/COPage/classes/class.ilPCTabs.php");
685  $map = new ilPCTabs($this->dom);
686  $map->setNode($cont_node);
687  $map->setHierId($a_hier_id);
688  $map->setPcId($a_pc_id);
689  return $map;
690 
691  case "Plugged":
692  require_once("./Services/COPage/classes/class.ilPCPlugged.php");
693  $plugged = new ilPCPlugged($this->dom);
694  $plugged->setNode($cont_node);
695  $plugged->setHierId($a_hier_id);
696  $plugged->setPcId($a_pc_id);
697  return $plugged;
698 
699  //Page-Layout-Support
700  case "PlaceHolder":
701  require_once("./Services/COPage/classes/class.ilPCPlaceHolder.php");
702  $placeholder = new ilPCPlaceHolder($this->dom);
703  $placeholder->setNode($cont_node);
704  $placeholder->setHierId($a_hier_id);
705  $placeholder->setPcId($a_pc_id);
706  return $placeholder;
707 
708  case "ContentInclude":
709  require_once("./Services/COPage/classes/class.ilPCContentInclude.php");
710  $inc =& new ilPCContentInclude($this->dom);
711  $inc->setNode($cont_node);
712  $inc->setHierId($a_hier_id);
713  $inc->setPcId($a_pc_id);
714  return $inc;
715  }
716  break;
717 
718  case "TableData":
719  require_once("./Services/COPage/classes/class.ilPCTableData.php");
720  $td =& new ilPCTableData($this->dom);
721  $td->setNode($cont_node);
722  $td->setHierId($a_hier_id);
723  return $td;
724 
725  case "ListItem":
726  require_once("./Services/COPage/classes/class.ilPCListItem.php");
727  $td =& new ilPCListItem($this->dom);
728  $td->setNode($cont_node);
729  $td->setHierId($a_hier_id);
730  return $td;
731 
732  case "FileItem":
733  require_once("./Services/COPage/classes/class.ilPCFileItem.php");
734  $file_item =& new ilPCFileItem($this->dom);
735  $file_item->setNode($cont_node);
736  $file_item->setHierId($a_hier_id);
737  return $file_item;
738 
739  case "Tab":
740  require_once("./Services/COPage/classes/class.ilPCTab.php");
741  $tab =& new ilPCTab($this->dom);
742  $tab->setNode($cont_node);
743  $tab->setHierId($a_hier_id);
744  return $file_item;
745 
746  }
747  }
748 
749  function &getContentNode($a_hier_id, $a_pc_id = "")
750  {
751  $xpc = xpath_new_context($this->dom);
752  if($a_hier_id == "pg")
753  {
754  return $this->node;
755  }
756  else
757  {
758  // get per pc id
759  if ($a_pc_id != "")
760  {
761  $path = "//*[@PCID = '$a_pc_id']";
762  $res =& xpath_eval($xpc, $path);
763  if (count($res->nodeset) == 1)
764  {
765  $cont_node =& $res->nodeset[0];
766  return $cont_node;
767  }
768  }
769 
770  // fall back to hier id
771  $path = "//*[@HierId = '$a_hier_id']";
772  $res =& xpath_eval($xpc, $path);
773  if (count($res->nodeset) == 1)
774  {
775  $cont_node =& $res->nodeset[0];
776  return $cont_node;
777  }
778  }
779  }
780 
781  // only for test purposes
782  function lookforhier($a_hier_id)
783  {
784  $xpc = xpath_new_context($this->dom);
785  $path = "//*[@HierId = '$a_hier_id']";
786  $res =& xpath_eval($xpc, $path);
787  if (count($res->nodeset) == 1)
788  return "YES";
789  else
790  return "NO";
791  }
792 
793 
794  function &getNode()
795  {
796  return $this->node;
797  }
798 
799 
808  function setXMLContent($a_xml, $a_encoding = "UTF-8")
809  {
810  $this->encoding = $a_encoding;
811  $this->xml = $a_xml;
812  }
813 
820  function appendXMLContent($a_xml)
821  {
822  $this->xml.= $a_xml;
823  }
824 
825 
829  function getXMLContent($a_incl_head = false)
830  {
831  // build full http path for XML DOCTYPE header.
832  // Under windows a relative path doesn't work :-(
833  if($a_incl_head)
834  {
835 //echo "+".$this->encoding."+";
836  $enc_str = (!empty($this->encoding))
837  ? "encoding=\"".$this->encoding."\""
838  : "";
839  return "<?xml version=\"1.0\" $enc_str ?>".
840  "<!DOCTYPE PageObject SYSTEM \"".ILIAS_ABSOLUTE_PATH."/xml/".$this->cur_dtd."\">".
841  $this->xml;
842  }
843  else
844  {
845  return $this->xml;
846  }
847  }
848 
853  function copyXmlContent($a_new_question_copies = true)
854  {
855  $xml = $this->getXmlContent();
856  $temp_dom = domxml_open_mem('<?xml version="1.0" encoding="UTF-8"?>'.$xml,
857  DOMXML_LOAD_PARSING, $error);
858 
859  if(empty($error))
860  {
861  if ($a_new_question_copies)
862  {
863  $this->newQuestionCopies($temp_dom);
864  }
865  }
866  $xml = $temp_dom->dump_mem(0, $this->encoding);
867  $xml = eregi_replace("<\?xml[^>]*>","",$xml);
868  $xml = eregi_replace("<!DOCTYPE[^>]*>","",$xml);
869 
870  return $xml;
871  }
872 
877  function newQuestionCopies(&$temp_dom)
878  {
879  // Get question IDs
880  $path = "//Question";
881  $xpc = xpath_new_context($temp_dom);
882  $res = & xpath_eval($xpc, $path);
883 
884  $q_ids = array();
885  include_once("./Services/COPage/classes/class.ilInternalLink.php");
886  for ($i = 0; $i < count ($res->nodeset); $i++)
887  {
888  $qref = $res->nodeset[$i]->get_attribute("QRef");
889 
890  $inst_id = ilInternalLink::_extractInstOfTarget($qref);
892 
893  if (!($inst_id > 0))
894  {
895  if ($q_id > 0)
896  {
897  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
898  $question = assQuestion::_instanciateQuestion($q_id);
899 
900  // now copy this question and change reference to
901  // new question id
902  $duplicate_id = $question->duplicate(false);
903  $res->nodeset[$i]->set_attribute("QRef", "il__qst_".$duplicate_id);
904  }
905  }
906  }
907  }
908 
913  function getXMLFromDom($a_incl_head = false, $a_append_mobs = false, $a_append_bib = false,
914  $a_append_str = "", $a_omit_pageobject_tag = false)
915  {
916  if ($a_incl_head)
917  {
918 //echo "\n<br>#".$this->encoding."#";
919  return $this->dom->dump_mem(0, $this->encoding);
920  }
921  else
922  {
923  // append multimedia object elements
924  if ($a_append_mobs || $a_append_bib || $a_append_link_info)
925  {
926  $mobs = "";
927  $bibs = "";
928  if ($a_append_mobs)
929  {
930  $mobs =& $this->getMultimediaXML();
931  }
932  if ($a_append_bib)
933  {
934  $bibs =& $this->getBibliographyXML();
935  }
936  $trans =& $this->getLanguageVariablesXML();
937  return "<dummy>".$this->dom->dump_node($this->node).$mobs.$bibs.$trans.$a_append_str."</dummy>";
938  }
939  else
940  {
941  if (is_object($this->dom))
942  {
943  if ($a_omit_pageobject_tag)
944  {
945  $xml = "";
946  $childs =& $this->node->child_nodes();
947  for($i = 0; $i < count($childs); $i++)
948  {
949  $xml.= $this->dom->dump_node($childs[$i]);
950  }
951  return $xml;
952  }
953  else
954  {
955  $xml = $this->dom->dump_mem(0, $this->encoding);
956  $xml = eregi_replace("<\?xml[^>]*>","",$xml);
957  $xml = eregi_replace("<!DOCTYPE[^>]*>","",$xml);
958 
959  return $xml;
960 
961  // don't use dump_node. This gives always entities.
962  //return $this->dom->dump_node($this->node);
963  }
964  }
965  else
966  {
967  return "";
968  }
969  }
970  }
971  }
972 
977  {
978  global $lng;
979 
980  $xml = "<LVs>";
981  $lang_vars = array("ed_insert_par", "ed_insert_code",
982  "ed_insert_dtable", "ed_insert_atable", "ed_insert_media", "ed_insert_list",
983  "ed_insert_filelist", "ed_paste_clip", "ed_edit", "ed_insert_section",
984  "ed_edit_prop","ed_edit_files", "ed_edit_data", "ed_delete", "ed_moveafter", "ed_movebefore",
985  "ed_go", "ed_new_row_after", "ed_new_row_before",
986  "ed_new_col_after", "ed_new_col_before", "ed_delete_col",
987  "ed_delete_row", "ed_class", "ed_width", "ed_align_left",
988  "ed_align_right", "ed_align_center", "ed_align_left_float",
989  "ed_align_right_float", "ed_delete_item", "ed_new_item_before",
990  "ed_new_item_after", "ed_copy_clip", "please_select", "ed_split_page",
991  "ed_item_up", "ed_item_down", "ed_row_up", "ed_row_down",
992  "ed_col_left", "ed_col_right", "ed_split_page_next","ed_enable",
993  "de_activate", "ed_insert_repobj", "ed_insert_map", "ed_insert_tabs",
994  "ed_insert_pcqst", "empty_question", "ed_paste","question_placeh","media_placeh","text_placeh",
995  "ed_insert_plach","question_placehl","media_placehl","text_placehl",
996  "pc_flist", "pc_par", "pc_mob", "pc_qst", "pc_sec", "pc_dtab", "pc_tab",
997  "pc_code", "pc_vacc", "pc_hacc", "pc_res", "pc_map", "pc_list", "ed_insert_incl", "pc_incl");
998 
999  foreach ($lang_vars as $lang_var)
1000  {
1001  $this->appendLangVarXML($xml, $lang_var);
1002  }
1003 
1004  $xml.= "</LVs>";
1005 
1006  return $xml;
1007  }
1008 
1009  function appendLangVarXML(&$xml, $var)
1010  {
1011  global $lng;
1012 
1013  $xml.= "<LV name=\"$var\" value=\"".$lng->txt("cont_".$var)."\"/>";
1014  }
1015 
1017  {
1018  require_once("./Services/COPage/classes/class.ilPCParagraph.php");
1019  $xpc = xpath_new_context($this->dom);
1020  $path = "//Paragraph[1]";
1021  $res =& xpath_eval($xpc, $path);
1022  if (count($res->nodeset) > 0)
1023  {
1024  $cont_node =& $res->nodeset[0]->parent_node();
1025  $par =& new ilPCParagraph($this->dom);
1026  $par->setNode($cont_node);
1027  return $par->getText();
1028  }
1029  else
1030  {
1031  return "";
1032  }
1033  }
1034 
1041  function setParagraphContent($a_hier_id, $a_content)
1042  {
1043  $node = $this->getContentNode($a_hier_id);
1044  if (is_object($node))
1045  {
1046  $node->set_content($a_content);
1047  }
1048  }
1049 
1050 
1059  function setContainsIntLink($a_contains_link)
1060  {
1061  $this->contains_int_link = $a_contains_link;
1062  }
1063 
1068  function containsIntLink()
1069  {
1070  return $this->contains_int_link;
1071  }
1072 
1073  function needsImportParsing($a_parse = "")
1074  {
1075 
1076  if ($a_parse === true)
1077  {
1078  $this->needs_parsing = true;
1079  }
1080  if ($a_parse === false)
1081  {
1082  $this->needs_parsing = false;
1083  }
1084  return $this->needs_parsing;
1085  }
1086 
1092  public function setContainsQuestion($a_val)
1093  {
1094  $this->contains_question = $a_val;
1095  }
1096 
1102  public function getContainsQuestion()
1103  {
1104  return $this->contains_question;
1105  }
1106 
1112  {
1113  global $ilias, $ilDB;
1114 
1115  // todo: access to $_GET and $_POST variables is not
1116  // allowed in non GUI classes!
1117  //
1118  // access to db table object_reference is not allowed here!
1119  $r = $ilias->db->query("SELECT * FROM object_reference WHERE ref_id=".
1120  $ilDB->quote($_GET["ref_id"],'integer'));
1121  $row = $r->fetchRow(DB_FETCHMODE_ASSOC);
1122 
1123  include_once("./classes/class.ilNestedSetXML.php");
1124  $nested = new ilNestedSetXML();
1125  $bibs_xml = $nested->export($row["obj_id"], "bib");
1126 
1127  return $bibs_xml;
1128  }
1129 
1130 
1135  function collectMediaObjects($a_inline_only = true)
1136  {
1137 //echo htmlentities($this->getXMLFromDom());
1138  // determine all media aliases of the page
1139  $xpc = xpath_new_context($this->dom);
1140  $path = "//MediaObject/MediaAlias";
1141  $res =& xpath_eval($xpc, $path);
1142  $mob_ids = array();
1143  for($i = 0; $i < count($res->nodeset); $i++)
1144  {
1145  $id_arr = explode("_", $res->nodeset[$i]->get_attribute("OriginId"));
1146  $mob_id = $id_arr[count($id_arr) - 1];
1147  $mob_ids[$mob_id] = $mob_id;
1148  }
1149 
1150  // determine all inline internal media links
1151  $xpc = xpath_new_context($this->dom);
1152  $path = "//IntLink[@Type = 'MediaObject']";
1153  $res =& xpath_eval($xpc, $path);
1154 
1155  for($i = 0; $i < count($res->nodeset); $i++)
1156  {
1157  if (($res->nodeset[$i]->get_attribute("TargetFrame") == "") ||
1158  (!$a_inline_only))
1159  {
1160  $target = $res->nodeset[$i]->get_attribute("Target");
1161  $id_arr = explode("_", $target);
1162  if (($id_arr[1] == IL_INST_ID) ||
1163  (substr($target, 0, 4) == "il__"))
1164  {
1165  $mob_id = $id_arr[count($id_arr) - 1];
1166  if (ilObject::_exists($mob_id))
1167  {
1168  $mob_ids[$mob_id] = $mob_id;
1169  }
1170  }
1171  }
1172  }
1173 
1174  return $mob_ids;
1175  }
1176 
1177 
1181  function getInternalLinks($a_cnt_multiple = false)
1182  {
1183  // get all internal links of the page
1184  $xpc = xpath_new_context($this->dom);
1185  $path = "//IntLink";
1186  $res =& xpath_eval($xpc, $path);
1187 
1188  $links = array();
1189  $cnt_multiple = 1;
1190  for($i = 0; $i < count($res->nodeset); $i++)
1191  {
1192  $add = "";
1193  if ($a_cnt_multiple)
1194  {
1195  $add = ":".$cnt_multiple;
1196  }
1197  $target = $res->nodeset[$i]->get_attribute("Target");
1198  $type = $res->nodeset[$i]->get_attribute("Type");
1199  $targetframe = $res->nodeset[$i]->get_attribute("TargetFrame");
1200  $anchor = $res->nodeset[$i]->get_attribute("Anchor");
1201  $links[$target.":".$type.":".$targetframe.":".$anchor.$add] =
1202  array("Target" => $target, "Type" => $type,
1203  "TargetFrame" => $targetframe, "Anchor" => $anchor);
1204 
1205  // get links (image map areas) for inline media objects
1206  if ($type == "MediaObject" && $targetframe == "")
1207  {
1208  if (substr($target, 0, 4) =="il__")
1209  {
1210  $id_arr = explode("_", $target);
1211  $id = $id_arr[count($id_arr) - 1];
1212 
1213  $med_links = ilMediaItem::_getMapAreasIntLinks($id);
1214  foreach($med_links as $key => $med_link)
1215  {
1216  $links[$key] = $med_link;
1217  }
1218  }
1219 
1220  }
1221 //echo "<br>-:".$target.":".$type.":".$targetframe.":-";
1222  $cnt_multiple++;
1223  }
1224  unset($xpc);
1225 
1226  // get all media aliases
1227  $xpc = xpath_new_context($this->dom);
1228  $path = "//MediaAlias";
1229  $res =& xpath_eval($xpc, $path);
1230 
1231  require_once("Services/MediaObjects/classes/class.ilMediaItem.php");
1232  for($i = 0; $i < count($res->nodeset); $i++)
1233  {
1234  $oid = $res->nodeset[$i]->get_attribute("OriginId");
1235  if (substr($oid, 0, 4) =="il__")
1236  {
1237  $id_arr = explode("_", $oid);
1238  $id = $id_arr[count($id_arr) - 1];
1239 
1240  $med_links = ilMediaItem::_getMapAreasIntLinks($id);
1241  foreach($med_links as $key => $med_link)
1242  {
1243  $links[$key] = $med_link;
1244  }
1245  }
1246  }
1247  unset($xpc);
1248 
1249  return $links;
1250  }
1251 
1255  function collectFileItems($a_xml = "")
1256  {
1257 //echo "<br>PageObject::collectFileItems[".$this->getId()."]";
1258  // determine all media aliases of the page
1259  if ($a_xml == "")
1260  {
1261  $xpc = xpath_new_context($this->dom);
1262  $doc = $this->dom;
1263  $path = "//FileItem/Identifier";
1264  $res =& xpath_eval($xpc, $path);
1265  }
1266  else
1267  {
1268  $doc = domxml_open_mem($a_xml);
1269  $xpc = xpath_new_context($doc);
1270  $path = "//FileItem/Identifier";
1271  $res =& xpath_eval($xpc, $path);
1272  }
1273  $file_ids = array();
1274  for($i = 0; $i < count($res->nodeset); $i++)
1275  {
1276  $id_arr = explode("_", $res->nodeset[$i]->get_attribute("Entry"));
1277  $file_id = $id_arr[count($id_arr) - 1];
1278  $file_ids[$file_id] = $file_id;
1279  }
1280 
1281  // file items in download links
1282  $xpc = xpath_new_context($doc);
1283  $path = "//IntLink[@Type='File']";
1284  $res =& xpath_eval($xpc, $path);
1285  for($i = 0; $i < count($res->nodeset); $i++)
1286  {
1287  $t = $res->nodeset[$i]->get_attribute("Target");
1288  if (substr($t, 0, 9) == "il__dfile")
1289  {
1290  $id_arr = explode("_", $t);
1291  $file_id = $id_arr[count($id_arr) - 1];
1292  $file_ids[$file_id] = $file_id;
1293  }
1294  }
1295 //var_dump($file_ids); exit;
1296  return $file_ids;
1297  }
1298 
1303  function getMultimediaXML()
1304  {
1305  $mob_ids = $this->collectMediaObjects();
1306 
1307  // get xml of corresponding media objects
1308  $mobs_xml = "";
1309  require_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
1310  foreach($mob_ids as $mob_id => $dummy)
1311  {
1312  if (ilObject::_lookupType($mob_id) == "mob")
1313  {
1314  $mob_obj =& new ilObjMediaObject($mob_id);
1315  $mobs_xml .= $mob_obj->getXML(IL_MODE_OUTPUT);
1316  }
1317  }
1318 //var_dump($mobs_xml);
1319  return $mobs_xml;
1320  }
1321 
1325  function getMediaAliasElement($a_mob_id, $a_nr = 1)
1326  {
1327  $xpc = xpath_new_context($this->dom);
1328  $path = "//MediaObject/MediaAlias[@OriginId='il__mob_$a_mob_id']";
1329  $res =& xpath_eval($xpc, $path);
1330  $mal_node =& $res->nodeset[$a_nr - 1];
1331  $mob_node =& $mal_node->parent_node();
1332 
1333  return $this->dom->dump_node($mob_node);
1334  }
1335 
1341  function validateDom()
1342  {
1343  $this->stripHierIDs();
1344  $this->dom->validate($error);
1345  return $error;
1346  }
1347 
1363  function addHierIDs()
1364  {
1365  $this->hier_ids = array();
1366  $this->first_row_ids = array();
1367  $this->first_col_ids = array();
1368  $this->list_item_ids = array();
1369  $this->file_item_ids = array();
1370 
1371  // set hierarchical ids for Paragraphs, Tables, TableRows and TableData elements
1372  $xpc = xpath_new_context($this->dom);
1373  //$path = "//Paragraph | //Table | //TableRow | //TableData";
1374 
1375  $sep = $path = "";
1376  foreach ($this->id_elements as $el)
1377  {
1378  $path.= $sep."//".$el;
1379  $sep = " | ";
1380  }
1381 
1382  $res =& xpath_eval($xpc, $path);
1383  for($i = 0; $i < count($res->nodeset); $i++)
1384  {
1385  $cnode = $res->nodeset[$i];
1386  $ctag = $cnode->node_name();
1387 
1388  // get hierarchical id of previous sibling
1389  $sib_hier_id = "";
1390  while($cnode =& $cnode->previous_sibling())
1391  {
1392  if (($cnode->node_type() == XML_ELEMENT_NODE)
1393  && $cnode->has_attribute("HierId"))
1394  {
1395  $sib_hier_id = $cnode->get_attribute("HierId");
1396  //$sib_hier_id = $id_attr->value();
1397  break;
1398  }
1399  }
1400 
1401  if ($sib_hier_id != "") // set id to sibling id "+ 1"
1402  {
1403  require_once("./Services/COPage/classes/class.ilPageContent.php");
1404  $node_hier_id = ilPageContent::incEdId($sib_hier_id);
1405  $res->nodeset[$i]->set_attribute("HierId", $node_hier_id);
1406  $this->hier_ids[] = $node_hier_id;
1407  if ($ctag == "TableData")
1408  {
1409  if (substr($par_hier_id,strlen($par_hier_id)-2) == "_1")
1410  {
1411  $this->first_row_ids[] = $node_hier_id;
1412  }
1413  }
1414  if ($ctag == "ListItem")
1415  {
1416  $this->list_item_ids[] = $node_hier_id;
1417  }
1418  if ($ctag == "FileItem")
1419  {
1420  $this->file_item_ids[] = $node_hier_id;
1421  }
1422  }
1423  else // no sibling -> node is first child
1424  {
1425  // get hierarchical id of next parent
1426  $cnode = $res->nodeset[$i];
1427  $par_hier_id = "";
1428  while($cnode =& $cnode->parent_node())
1429  {
1430  if (($cnode->node_type() == XML_ELEMENT_NODE)
1431  && $cnode->has_attribute("HierId"))
1432  {
1433  $par_hier_id = $cnode->get_attribute("HierId");
1434  //$par_hier_id = $id_attr->value();
1435  break;
1436  }
1437  }
1438 //echo "<br>par:".$par_hier_id." ($ctag)";
1439  if (($par_hier_id != "") && ($par_hier_id != "pg")) // set id to parent_id."_1"
1440  {
1441  $node_hier_id = $par_hier_id."_1";
1442  $res->nodeset[$i]->set_attribute("HierId", $node_hier_id);
1443  $this->hier_ids[] = $node_hier_id;
1444  if ($ctag == "TableData")
1445  {
1446  $this->first_col_ids[] = $node_hier_id;
1447  if (substr($par_hier_id,strlen($par_hier_id)-2) == "_1")
1448  {
1449  $this->first_row_ids[] = $node_hier_id;
1450  }
1451  }
1452  if ($ctag == "ListItem")
1453  {
1454  $this->list_item_ids[] = $node_hier_id;
1455  }
1456  if ($ctag == "FileItem")
1457  {
1458  $this->file_item_ids[] = $node_hier_id;
1459  }
1460 
1461  }
1462  else // no sibling, no parent -> first node
1463  {
1464  $node_hier_id = "1";
1465  $res->nodeset[$i]->set_attribute("HierId", $node_hier_id);
1466  $this->hier_ids[] = $node_hier_id;
1467  }
1468  }
1469  }
1470 
1471  // set special hierarchical id "pg" for pageobject
1472  $xpc = xpath_new_context($this->dom);
1473  $path = "//PageObject";
1474  $res =& xpath_eval($xpc, $path);
1475  for($i = 0; $i < count($res->nodeset); $i++) // should only be 1
1476  {
1477  $res->nodeset[$i]->set_attribute("HierId", "pg");
1478  $this->hier_ids[] = "pg";
1479  }
1480  unset($xpc);
1481  }
1482 
1486  function getHierIds()
1487  {
1488  return $this->hier_ids;
1489  }
1490 
1494  function getFirstRowIds()
1495  {
1496  return $this->first_row_ids;
1497  }
1498 
1503  {
1504  return $this->first_col_ids;
1505  }
1506 
1510  function getListItemIds()
1511  {
1512  return $this->list_item_ids;
1513  }
1514 
1518  function getFileItemIds()
1519  {
1520  return $this->file_item_ids;
1521  }
1522 
1526  function stripHierIDs()
1527  {
1528  if(is_object($this->dom))
1529  {
1530  $xpc = xpath_new_context($this->dom);
1531  $path = "//*[@HierId]";
1532  $res =& xpath_eval($xpc, $path);
1533  for($i = 0; $i < count($res->nodeset); $i++) // should only be 1
1534  {
1535  if ($res->nodeset[$i]->has_attribute("HierId"))
1536  {
1537  $res->nodeset[$i]->remove_attribute("HierId");
1538  }
1539  }
1540  unset($xpc);
1541  }
1542  }
1543 
1547  function addFileSizes()
1548  {
1549  $xpc = xpath_new_context($this->dom);
1550  $path = "//FileItem";
1551  $res =& xpath_eval($xpc, $path);
1552  for($i = 0; $i < count($res->nodeset); $i++)
1553  {
1554  $cnode =& $res->nodeset[$i];
1555  $size_node =& $this->dom->create_element("Size");
1556  $size_node =& $cnode->append_child($size_node);
1557 
1558  $childs =& $cnode->child_nodes();
1559  $size = "";
1560  for($j = 0; $j < count($childs); $j++)
1561  {
1562  if ($childs[$j]->node_name() == "Identifier")
1563  {
1564  if ($childs[$j]->has_attribute("Entry"))
1565  {
1566  $entry = $childs[$j]->get_attribute("Entry");
1567  $entry_arr = explode("_", $entry);
1568  $id = $entry_arr[count($entry_arr) - 1];
1569  require_once("./Modules/File/classes/class.ilObjFile.php");
1571  }
1572  }
1573  }
1574  $size_node->set_content($size);
1575  }
1576 
1577  unset($xpc);
1578  }
1579 
1584  function resolveIntLinks()
1585  {
1586  // resolve normal internal links
1587  $xpc = xpath_new_context($this->dom);
1588  $path = "//IntLink";
1589  $res =& xpath_eval($xpc, $path);
1590  for($i = 0; $i < count($res->nodeset); $i++)
1591  {
1592  $target = $res->nodeset[$i]->get_attribute("Target");
1593  $type = $res->nodeset[$i]->get_attribute("Type");
1594 
1595  $new_target = ilInternalLink::_getIdForImportId($type, $target);
1596  if ($new_target !== false)
1597  {
1598  $res->nodeset[$i]->set_attribute("Target", $new_target);
1599  }
1600  else // check wether link target is same installation
1601  {
1602  if (ilInternalLink::_extractInstOfTarget($target) == IL_INST_ID &&
1603  IL_INST_ID > 0 && $type != "RepositoryItem")
1604  {
1605  $new_target = ilInternalLink::_removeInstFromTarget($target);
1606  if (ilInternalLink::_exists($type, $new_target))
1607  {
1608  $res->nodeset[$i]->set_attribute("Target", $new_target);
1609  }
1610  }
1611  }
1612 
1613  }
1614  unset($xpc);
1615 
1616  // resolve internal links in map areas
1617  $xpc = xpath_new_context($this->dom);
1618  $path = "//MediaAlias";
1619  $res =& xpath_eval($xpc, $path);
1620 //echo "<br><b>page::resolve</b><br>";
1621 //echo "Content:".htmlentities($this->getXMLFromDOM()).":<br>";
1622  for($i = 0; $i < count($res->nodeset); $i++)
1623  {
1624  $orig_id = $res->nodeset[$i]->get_attribute("OriginId");
1625  $id_arr = explode("_", $orig_id);
1626  $mob_id = $id_arr[count($id_arr) - 1];
1628  }
1629  }
1630 
1637  function resolveMediaAliases($a_mapping)
1638  {
1639  // resolve normal internal links
1640  $xpc = xpath_new_context($this->dom);
1641  $path = "//MediaAlias";
1642  $res =& xpath_eval($xpc, $path);
1643  $changed = false;
1644  for($i = 0; $i < count($res->nodeset); $i++)
1645  {
1646  $old_id = $res->nodeset[$i]->get_attribute("OriginId");
1647  $old_id = explode("_", $old_id);
1648  $old_id = $old_id[count($old_id) - 1];
1649  if ($a_mapping[$old_id] > 0)
1650  {
1651  $res->nodeset[$i]->set_attribute("OriginId", "il__mob_".$a_mapping[$old_id]);
1652  $changed = true;
1653  }
1654  }
1655  unset($xpc);
1656 
1657  return $changed;
1658  }
1659 
1666  function resolveFileItems($a_mapping)
1667  {
1668  // resolve normal internal links
1669  $xpc = xpath_new_context($this->dom);
1670  $path = "//FileItem/Identifier";
1671  $res =& xpath_eval($xpc, $path);
1672  $changed = false;
1673  for($i = 0; $i < count($res->nodeset); $i++)
1674  {
1675  $old_id = $res->nodeset[$i]->get_attribute("Entry");
1676  $old_id = explode("_", $old_id);
1677  $old_id = $old_id[count($old_id) - 1];
1678  if ($a_mapping[$old_id] > 0)
1679  {
1680  $res->nodeset[$i]->set_attribute("Entry", "il__file_".$a_mapping[$old_id]);
1681  $changed = true;
1682  }
1683  }
1684  unset($xpc);
1685 
1686  return $changed;
1687  }
1688 
1693  function resolveQuestionReferences($a_mapping)
1694  {
1695  // resolve normal internal links
1696  $xpc = xpath_new_context($this->dom);
1697  $path = "//Question";
1698  $res =& xpath_eval($xpc, $path);
1699  for($i = 0; $i < count($res->nodeset); $i++)
1700  {
1701  $qref = $res->nodeset[$i]->get_attribute("QRef");
1702 
1703  if (isset($a_mapping[$qref]))
1704  {
1705  $res->nodeset[$i]->set_attribute("QRef", "il__qst_".$a_mapping[$qref]["pool"]);
1706  }
1707  }
1708  unset($xpc);
1709  }
1710 
1711 
1718  function moveIntLinks($a_from_to)
1719  {
1720  $this->buildDom();
1721 
1722  $changed = false;
1723 
1724  // resolve normal internal links
1725  $xpc = xpath_new_context($this->dom);
1726  $path = "//IntLink";
1727  $res =& xpath_eval($xpc, $path);
1728  for($i = 0; $i < count($res->nodeset); $i++)
1729  {
1730  $target = $res->nodeset[$i]->get_attribute("Target");
1731  $type = $res->nodeset[$i]->get_attribute("Type");
1732  $obj_id = ilInternalLink::_extractObjIdOfTarget($target);
1733  if ($a_from_to[$obj_id] > 0 && is_int(strpos($target, "__")))
1734  {
1735  if ($type == "PageObject" && ilLMObject::_lookupType($a_from_to[$obj_id]) == "pg")
1736  {
1737  $res->nodeset[$i]->set_attribute("Target", "il__pg_".$a_from_to[$obj_id]);
1738  $changed = true;
1739  }
1740  if ($type == "StructureObject" && ilLMObject::_lookupType($a_from_to[$obj_id]) == "st")
1741  {
1742  $res->nodeset[$i]->set_attribute("Target", "il__st_".$a_from_to[$obj_id]);
1743  $changed = true;
1744  }
1745  }
1746  }
1747  unset($xpc);
1748 
1749  // map areas
1750  $this->addHierIDs();
1751  $xpc = xpath_new_context($this->dom);
1752  $path = "//MediaAlias";
1753  $res =& xpath_eval($xpc, $path);
1754 
1755  require_once("Services/MediaObjects/classes/class.ilMediaItem.php");
1756  require_once("Services/COPage/classes/class.ilMediaAliasItem.php");
1757 
1758  for($i = 0; $i < count($res->nodeset); $i++)
1759  {
1760  $media_object_node = $res->nodeset[$i]->parent_node();
1761  $page_content_node = $media_object_node->parent_node();
1762  $c_hier_id = $page_content_node->get_attribute("HierId");
1763 
1764  // first check, wheter we got instance map areas -> take these
1765  $std_alias_item = new ilMediaAliasItem($this->dom,
1766  $c_hier_id, "Standard");
1767  $areas = $std_alias_item->getMapAreas();
1768  $correction_needed = false;
1769  if (count($areas) > 0)
1770  {
1771  // check if correction needed
1772  foreach($areas as $area)
1773  {
1774  if ($area["Type"] == "PageObject" ||
1775  $area["Type"] == "StructureObject")
1776  {
1777  $t = $area["Target"];
1778  $tid = _extractObjIdOfTarget($t);
1779  if ($a_from_to[$tid] > 0)
1780  {
1781  $correction_needed = true;
1782  }
1783  }
1784  }
1785  }
1786  else
1787  {
1788  $areas = array();
1789 
1790  // get object map areas and check whether at least one must
1791  // be corrected
1792  $oid = $res->nodeset[$i]->get_attribute("OriginId");
1793  if (substr($oid, 0, 4) =="il__")
1794  {
1795  $id_arr = explode("_", $oid);
1796  $id = $id_arr[count($id_arr) - 1];
1797 
1798  $mob = new ilObjMediaObject($id);
1799  $med_item = $mob->getMediaItem("Standard");
1800  $med_areas = $med_item->getMapAreas();
1801 
1802  foreach($med_areas as $area)
1803  {
1804  $link_type = ($area->getLinkType() == "int")
1805  ? "IntLink"
1806  : "ExtLink";
1807 
1808  $areas[] = array(
1809  "Nr" => $area->getNr(),
1810  "Shape" => $area->getShape(),
1811  "Coords" => $area->getCoords(),
1812  "Link" => array(
1813  "LinkType" => $link_type,
1814  "Href" => $area->getHref(),
1815  "Title" => $area->getTitle(),
1816  "Target" => $area->getTarget(),
1817  "Type" => $area->getType(),
1818  "TargetFrame" => $area->getTargetFrame()
1819  )
1820  );
1821 
1822  if ($area->getType() == "PageObject" ||
1823  $area->getType() == "StructureObject")
1824  {
1825  $t = $area->getTarget();
1827  if ($a_from_to[$tid] > 0)
1828  {
1829  $correction_needed = true;
1830  }
1831 //var_dump($a_from_to);
1832  }
1833  }
1834  }
1835  }
1836 
1837  // correct map area links
1838  if ($correction_needed)
1839  {
1840  $changed = true;
1841  $std_alias_item->deleteAllMapAreas();
1842  foreach($areas as $area)
1843  {
1844  if ($area["Link"]["LinkType"] == "IntLink")
1845  {
1846  $target = $area["Link"]["Target"];
1847  $type = $area["Link"]["Type"];
1848  $obj_id = ilInternalLink::_extractObjIdOfTarget($target);
1849  if ($a_from_to[$obj_id] > 0)
1850  {
1851  if ($type == "PageObject" && ilLMObject::_lookupType($a_from_to[$obj_id]) == "pg")
1852  {
1853  $area["Link"]["Target"] = "il__pg_".$a_from_to[$obj_id];
1854  }
1855  if ($type == "StructureObject" && ilLMObject::_lookupType($a_from_to[$obj_id]) == "st")
1856  {
1857  $area["Link"]["Target"] = "il__st_".$a_from_to[$obj_id];
1858  }
1859  }
1860  }
1861 
1862  $std_alias_item->addMapArea($area["Shape"], $area["Coords"],
1863  $area["Link"]["Title"],
1864  array( "Type" => $area["Link"]["Type"],
1865  "TargetFrame" => $area["Link"]["TargetFrame"],
1866  "Target" => $area["Link"]["Target"],
1867  "Href" => $area["Link"]["Href"],
1868  "LinkType" => $area["Link"]["LinkType"],
1869  ));
1870  }
1871  }
1872  }
1873  unset($xpc);
1874 
1875  return $changed;
1876  }
1877 
1883  static function _handleImportRepositoryLinks($a_rep_import_id, $a_rep_type, $a_rep_ref_id)
1884  {
1885  include_once("./Services/COPage/classes/class.ilInternalLink.php");
1886 
1887 //echo "-".$a_rep_import_id."-".$a_rep_ref_id."-";
1888  $sources = ilInternalLink::_getSourcesOfTarget("obj",
1889  ilInternalLink::_extractObjIdOfTarget($a_rep_import_id),
1890  ilInternalLink::_extractInstOfTarget($a_rep_import_id));
1891 //var_dump($sources);
1892  foreach($sources as $source)
1893  {
1894 //echo "A";
1895  if ($source["type"] == "lm:pg")
1896  {
1897 //echo "B";
1898  $page_obj = new ilPageObject("lm", $source["id"], false);
1899  if (!$page_obj->page_not_found)
1900  {
1901 //echo "C";
1902  $page_obj->handleImportRepositoryLink($a_rep_import_id,
1903  $a_rep_type, $a_rep_ref_id);
1904  }
1905  $page_obj->update();
1906  }
1907  }
1908  }
1909 
1910  function handleImportRepositoryLink($a_rep_import_id, $a_rep_type, $a_rep_ref_id)
1911  {
1912  $this->buildDom();
1913 
1914  // resolve normal internal links
1915  $xpc = xpath_new_context($this->dom);
1916  $path = "//IntLink";
1917  $res =& xpath_eval($xpc, $path);
1918 //echo "1";
1919  for($i = 0; $i < count($res->nodeset); $i++)
1920  {
1921 //echo "2";
1922  $target = $res->nodeset[$i]->get_attribute("Target");
1923  $type = $res->nodeset[$i]->get_attribute("Type");
1924  if ($target == $a_rep_import_id && $type == "RepositoryItem")
1925  {
1926 //echo "setting:"."il__".$a_rep_type."_".$a_rep_ref_id;
1927  $res->nodeset[$i]->set_attribute("Target",
1928  "il__".$a_rep_type."_".$a_rep_ref_id);
1929  }
1930  }
1931  unset($xpc);
1932  }
1933 
1937  function createFromXML()
1938  {
1939  global $lng, $ilDB, $ilUser;
1940 
1941 //echo "<br>PageObject::createFromXML[".$this->getId()."]";
1942 
1943  if($this->getXMLContent() == "")
1944  {
1945  $this->setXMLContent("<PageObject></PageObject>");
1946  }
1947 
1948  $iel = $this->containsDeactivatedElements($this->getXMLContent());
1949  $inl = $this->containsIntLinks($this->getXMLContent());
1950 
1951  // create object
1952  /* $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 ".
1953  "(".$ilDB->quote($this->getId()).",".
1954  $ilDB->quote($this->getParentId()).",".
1955  $ilDB->quote($this->getXMLContent()).
1956  ", ".$ilDB->quote($this->getParentType()).
1957  ", ".$ilDB->quote($ilUser->getId()).
1958  ", ".$ilDB->quote($ilUser->getId()).
1959  ", ".$ilDB->quote($iel, "integer")." ".
1960  ", ".$ilDB->quote($inl, "integer")." ".
1961  ", now(), now())"; */
1962 
1963  $ilDB->insert("page_object", array(
1964  "page_id" => array("integer", $this->getId()),
1965  "parent_id" => array("integer", $this->getParentId()),
1966  "content" => array("clob", $this->getXMLContent()),
1967  "parent_type" => array("text", $this->getParentType()),
1968  "create_user" => array("integer", $ilUser->getId()),
1969  "last_change_user" => array("integer", $ilUser->getId()),
1970  "inactive_elements" => array("integer", $iel),
1971  "int_links" => array("integer", $inl),
1972  "created" => array("timestamp", ilUtil::now()),
1973  "last_change" => array("timestamp", ilUtil::now())
1974  ));
1975 
1976 // todo: put this into insert
1977 /* if(!$ilDB->checkQuerySize($query))
1978  {
1979  $this->ilias->raiseError($lng->txt("check_max_allowed_packet_size"),$this->ilias->error_obj->MESSAGE);
1980  return false;
1981  }*/
1982 
1983 // $ilDB->query($query);
1984  }
1985 
1986 
1990  function updateFromXML()
1991  {
1992  global $lng, $ilDB, $ilUser;
1993 
1994 //echo "<br>PageObject::updateFromXML[".$this->getId()."]";
1995 //echo "update:".ilUtil::prepareDBString(($this->getXMLContent())).":<br>";
1996 //echo "update:".htmlentities($this->getXMLContent()).":<br>";
1997 
1998  $iel = $this->containsDeactivatedElements($this->getXMLContent());
1999  $inl = $this->containsIntLinks($this->getXMLContent());
2000 
2001  /*$query = "UPDATE page_object ".
2002  "SET content = ".$ilDB->quote($this->getXMLContent())." ".
2003  ", parent_id = ".$ilDB->quote($this->getParentId())." ".
2004  ", last_change_user = ".$ilDB->quote($ilUser->getId())." ".
2005  ", last_change = now() ".
2006  ", active = ".$ilDB->quote($this->getActive())." ".
2007  ", activation_start = ".$ilDB->quote($this->getActivationStart())." ".
2008  ", activation_end = ".$ilDB->quote($this->getActivationEnd())." ".
2009  ", inactive_elements = ".$ilDB->quote($iel, "integer")." ".
2010  ", int_links = ".$ilDB->quote($inl, "integer")." ".
2011  "WHERE page_id = ".$ilDB->quote($this->getId())." AND parent_type=".
2012  $ilDB->quote($this->getParentType());*/
2013 
2014  $ilDB->update("page_object", array(
2015  "content" => array("clob", $this->getXMLContent()),
2016  "parent_id" => array("integer", $this->getParentId()),
2017  "last_change_user" => array("integer", $ilUser->getId()),
2018  "last_change" => array("timestamp", ilUtil::now()),
2019  "active" => array("integer", $this->getActive()),
2020  "activation_start" => array("timestamp", $this->getActivationStart()),
2021  "activation_end" => array("timestamp", $this->getActivationEnd()),
2022  "inactive_elements" => array("integer", $iel),
2023  "int_links" => array("integer", $inl),
2024  ), array(
2025  "page_id" => array("integer", $this->getId()),
2026  "parent_type" => array("text", $this->getParentType())
2027  ));
2028 
2029 // todo: move this to update
2030 /* if(!$ilDB->checkQuerySize($query))
2031  {
2032  $this->ilias->raiseError($lng->txt("check_max_allowed_packet_size"),$this->ilias->error_obj->MESSAGE);
2033  return false;
2034  }
2035  $ilDB->query($query);*/
2036 // save style usage
2037  $this->saveStyleUsage($this->getXMLContent());
2038 
2039  // save internal link information
2040  $this->saveInternalLinks($this->getXMLContent());
2041  return true;
2042  }
2043 
2047  function update($a_validate = true, $a_no_history = false, $skip_handle_usages = false)
2048  {
2049  global $lng, $ilDB, $ilUser, $ilLog, $ilCtrl;
2050 
2051 //echo "<br>**".$this->getId()."**";
2052 //echo "<br>PageObject::update[".$this->getId()."],validate($a_validate)";
2053 //echo "\n<br>dump_all2:".$this->dom->dump_mem(0, "UTF-8").":";
2054 //echo "\n<br>PageObject::update:".$this->getXMLFromDom().":";
2055 //echo "<br>PageObject::update:".htmlentities($this->getXMLFromDom());
2056 
2057  // add missing pc ids
2058  if (!$this->checkPCIds())
2059  {
2060  $this->insertPCIds();
2061  }
2062 
2063  // test validating
2064  if($a_validate)
2065  {
2066  $errors = $this->validateDom();
2067  }
2068 
2069 //echo "-".htmlentities($this->getXMLFromDom())."-"; exit;
2070  if(empty($errors))
2071  {
2073 
2074  $content = $this->getXMLFromDom();
2075 
2076  // this needs to be locked
2077 
2078  // write history entry
2079  $old_set = $ilDB->query("SELECT * FROM page_object WHERE ".
2080  "page_id = ".$ilDB->quote($this->getId(), "integer")." AND ".
2081  "parent_type = ".$ilDB->quote($this->getParentType(), "text"));
2082  $last_nr_set = $ilDB->query("SELECT max(nr) as mnr FROM page_history WHERE ".
2083  "page_id = ".$ilDB->quote($this->getId(), "integer")." AND ".
2084  "parent_type = ".$ilDB->quote($this->getParentType(), "text"));
2085  $last_nr = $ilDB->fetchAssoc($last_nr_set);
2086  if ($old_rec = $ilDB->fetchAssoc($old_set))
2087  {
2088  // only save, if something has changed and not in layout mode
2089  if (($content != $old_rec["content"]) && !$a_no_history &&
2090  !$this->history_saved && !$this->layout_mode)
2091  {
2092  if ($old_rec["content"] != "<PageObject></PageObject>")
2093  {
2094  $ilDB->manipulateF("DELETE FROM page_history WHERE ".
2095  "page_id = %s AND parent_type = %s AND hdate = %s",
2096  array("integer", "text", "timestamp"),
2097  array($old_rec["page_id"], $old_rec["parent_type"], $old_rec["last_change"]));
2098 
2099  // the following lines are a workaround for
2100  // bug 6741
2101  $last_c = $old_rec["last_change"];
2102  if ($last_c == "")
2103  {
2104  $last_c = ilUtil::now();
2105  }
2106 
2107  $ilDB->insert("page_history", array(
2108  "page_id" => array("integer", $old_rec["page_id"]),
2109  "parent_type" => array("text", $old_rec["parent_type"]),
2110  "hdate" => array("timestamp", $last_c),
2111  "parent_id" => array("integer", $old_rec["parent_id"]),
2112  "content" => array("clob", $old_rec["content"]),
2113  "user_id" => array("integer", $old_rec["last_change_user"]),
2114  "ilias_version" => array("text", ILIAS_VERSION_NUMERIC),
2115  "nr" => array("integer", (int) $last_nr["mnr"] + 1)
2116  ));
2117  /*$h_query = "REPLACE INTO page_history ".
2118  "(page_id, parent_type, hdate, parent_id, content, user_id, ilias_version, nr) VALUES (".
2119  $ilDB->quote($old_rec["page_id"]).",".
2120  $ilDB->quote($old_rec["parent_type"]).",".
2121  $ilDB->quote($old_rec["last_change"]).",".
2122  $ilDB->quote($old_rec["parent_id"]).",".
2123  $ilDB->quote($old_rec["content"]).",".
2124  $ilDB->quote($old_rec["last_change_user"]).",".
2125  $ilDB->quote(ILIAS_VERSION_NUMERIC).",".
2126  $ilDB->quote($last_nr["mnr"] + 1).")";
2127 //echo "<br><br>+$a_no_history+$h_query";
2128  $ilDB->query($h_query);*/
2129  $this->saveMobUsage($old_rec["content"], $last_nr["mnr"] + 1);
2130  $this->saveStyleUsage($old_rec["content"], $last_nr["mnr"] + 1);
2131  $this->saveFileUsage($old_rec["content"], $last_nr["mnr"] + 1);
2132  $this->saveContentIncludeUsage($old_rec["content"], $last_nr["mnr"] + 1);
2133  $this->history_saved = true; // only save one time
2134  }
2135  else
2136  {
2137  $this->history_saved = true; // do not save on first change
2138  }
2139  }
2140  }
2141 //echo htmlentities($content);
2142  $em = (trim($content) == "<PageObject/>")
2143  ? 1
2144  : 0;
2145 
2146  $iel = $this->containsDeactivatedElements($content);
2147  $inl = $this->containsIntLinks($content);
2148  /*$query = "UPDATE page_object ".
2149  "SET content = ".$ilDB->quote($content)." ".
2150  ", parent_id= ".$ilDB->quote($this->getParentId())." ".
2151  ", last_change_user= ".$ilDB->quote($ilUser->getId())." ".
2152  ", last_change = now() ".
2153  ", is_empty = ".$ilDB->quote($em, "integer")." ".
2154  ", active = ".$ilDB->quote($this->getActive())." ".
2155  ", activation_start = ".$ilDB->quote($this->getActivationStart())." ".
2156  ", activation_end = ".$ilDB->quote($this->getActivationEnd())." ".
2157  ", inactive_elements = ".$ilDB->quote($iel, "integer")." ".
2158  ", int_links = ".$ilDB->quote($inl, "integer")." ".
2159  " WHERE page_id = ".$ilDB->quote($this->getId()).
2160  " AND parent_type= ".$ilDB->quote($this->getParentType());*/
2161 
2162  $ilDB->update("page_object", array(
2163  "content" => array("clob", $content),
2164  "parent_id" => array("integer", $this->getParentId()),
2165  "last_change_user" => array("integer", $ilUser->getId()),
2166  "last_change" => array("timestamp", ilUtil::now()),
2167  "is_empty" => array("integer", $em),
2168  "active" => array("integer", $this->getActive()),
2169  "activation_start" => array("timestamp", $this->getActivationStart()),
2170  "activation_end" => array("timestamp", $this->getActivationEnd()),
2171  "inactive_elements" => array("integer", $iel),
2172  "int_links" => array("integer", $inl),
2173  ), array(
2174  "page_id" => array("integer", $this->getId()),
2175  "parent_type" => array("text", $this->getParentType())
2176  ));
2177 
2178 // todo put this into update function
2179 /* if(!$this->ilias->db->checkQuerySize($query))
2180  {
2181  $this->ilias->raiseError($lng->txt("check_max_allowed_packet_size"),$this->ilias->error_obj->MESSAGE);
2182  return false;
2183  }*/
2184 
2185 // $this->ilias->db->query($query);
2186 
2187  if (!$skip_handle_usages)
2188  {
2189  // handle media object usage
2190  include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
2192  $this->getParentType().":pg", $this->getId());
2193  $this->saveMobUsage($this->getXMLFromDom());
2194  $this->saveMetaKeywords($this->getXMLFromDom());
2195  foreach($mob_ids as $mob) // check, whether media object can be deleted
2196  {
2197  if (ilObject::_exists($mob) && ilObject::_lookupType($mob) == "mob")
2198  {
2199  $mob_obj = new ilObjMediaObject($mob);
2200  $usages = $mob_obj->getUsages(false);
2201  if (count($usages) == 0) // delete, if no usage exists
2202  {
2203  $mob_obj->delete();
2204  }
2205  }
2206  }
2207 
2208  // handle file usages
2209  include_once("./Modules/File/classes/class.ilObjFile.php");
2210  $file_ids = ilObjFile::_getFilesOfObject(
2211  $this->getParentType().":pg", $this->getId());
2212  $this->saveFileUsage();
2213  foreach($file_ids as $file) // check, whether file object can be deleted
2214  {
2215  if (ilObject::_exists($file))
2216  {
2217  $file_obj = new ilObjFile($file, false);
2218  $usages = $file_obj->getUsages();
2219  if (count($usages) == 0) // delete, if no usage exists
2220  {
2221  if ($file_obj->getMode() == "filelist") // non-repository object
2222  {
2223  $file_obj->delete();
2224  }
2225  }
2226  }
2227  }
2228 
2229  // save style usage
2230  $this->saveStyleUsage($this->getXMLFromDom());
2231 
2232  // save content include usage
2233  $this->saveContentIncludeUsage($this->getXMLFromDom());
2234  }
2235 
2236  // save internal link information
2237  $this->saveInternalLinks($this->getXMLFromDom());
2238  $this->saveAnchors($this->getXMLFromDom());
2239  $this->callUpdateListeners();
2240 //echo "<br>PageObject::update:".htmlentities($this->getXMLContent()).":";
2241  return true;
2242  }
2243  else
2244  {
2245  return $errors;
2246  }
2247  }
2248 
2249 
2253  function delete()
2254  {
2255  global $ilDB;
2256 
2257  $mobs = array();
2258  $files = array();
2259 
2260  if (!$this->page_not_found)
2261  {
2262  $this->buildDom();
2263  $mobs = $this->collectMediaObjects(false);
2264  $files = $this->collectFileItems();
2265  }
2266 
2267  // delete mob usages
2268  $this->saveMobUsage("<dummy></dummy>");
2269 
2270  // delete style usages
2271  $this->saveStyleUsage("<dummy></dummy>");
2272 
2273  // delete style usages
2274  $this->saveContentIncludeUsage("<dummy></dummy>");
2275 
2276  // delete internal links
2277  $this->saveInternalLinks("<dummy></dummy>");
2278 
2279  // delete anchors
2280  $this->saveAnchors("<dummy></dummy>");
2281 
2282  // delete all file usages
2283  include_once("./Modules/File/classes/class.ilObjFile.php");
2284  ilObjFile::_deleteAllUsages($this->getParentType().":pg", $this->getId());
2285 
2286  // delete news
2287  include_once("./Services/News/classes/class.ilNewsItem.php");
2289  $this->getParentType(), $this->getId(), "pg");
2290 
2291  // delete page_object entry
2292  $ilDB->manipulate("DELETE FROM page_object ".
2293  "WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
2294  " AND parent_type= ".$ilDB->quote($this->getParentType(), "text"));
2295  //$this->ilias->db->query($query);
2296 
2297  // delete media objects
2298  foreach ($mobs as $mob_id)
2299  {
2300  if(ilObject::_lookupType($mob_id) != 'mob')
2301  {
2302  $GLOBALS['ilLog']->write(__METHOD__.': Type mismatch. Ignoring mob with id: '.$mob_id);
2303  continue;
2304  }
2305 
2306  if (ilObject::_exists($mob_id))
2307  {
2308  $mob_obj =& new ilObjMediaObject($mob_id);
2309  $mob_obj->delete();
2310  }
2311  }
2312 
2313  include_once("./Modules/File/classes/class.ilObjFile.php");
2314  foreach ($files as $file_id)
2315  {
2316  if (ilObject::_exists($file_id))
2317  {
2318  $file_obj =& new ilObjFile($file_id, false);
2319  $file_obj->delete();
2320  }
2321  }
2322 
2323  }
2324 
2330  function saveMetaKeywords($a_xml)
2331  {
2332  // not nice, should be set by context per method
2333  if ($this->getParentType() == "gdf" ||
2334  $this->getParentType() == "lm" ||
2335  $this->getParentType() == "dbk")
2336  {
2337  $doc = domxml_open_mem($a_xml);
2338 
2339  // get existing keywords
2340  $keywords = array();
2341 
2342  // find all Keyw tags
2343  $xpc = xpath_new_context($doc);
2344  $path = "//Keyw";
2345  $res = xpath_eval($xpc, $path);
2346  for ($i=0; $i < count($res->nodeset); $i++)
2347  {
2348  $k = trim(strip_tags($res->nodeset[$i]->get_content()));
2349  if (!in_array($k, $keywords))
2350  {
2351  $keywords[] = $k;
2352  }
2353  }
2354 
2355  $meta_type = ($this->getParentType() == "gdf")
2356  ? "gdf"
2357  : "pg";
2358  $meta_rep_id = $this->getParentId();
2359  $meta_id = $this->getId();
2360 
2361  include_once("./Services/MetaData/classes/class.ilMD.php");
2362  $md_obj = new ilMD($meta_rep_id, $meta_id, $meta_type);
2363  $mkeywords = array();
2364  $lang = "";
2365  if(is_object($md_section = $md_obj->getGeneral()))
2366  {
2367  foreach($ids = $md_section->getKeywordIds() as $id)
2368  {
2369  $md_key = $md_section->getKeyword($id);
2370  $mkeywords[] = strtolower($md_key->getKeyword());
2371  if ($lang == "")
2372  {
2373  $lang = $md_key->getKeywordLanguageCode();
2374  }
2375  }
2376  }
2377  if ($lang == "")
2378  {
2379  foreach($ids = $md_section->getLanguageIds() as $id)
2380  {
2381  $md_lang = $md_section->getLanguage($id);
2382  if ($lang == "")
2383  {
2384  $lang = $md_lang->getLanguageCode();
2385  }
2386  }
2387  }
2388  foreach ($keywords as $k)
2389  {
2390  if (!in_array(strtolower($k), $mkeywords))
2391  {
2392  if (trim($k) != "" && $lang != "")
2393  {
2394  $md_key = $md_section->addKeyword();
2395  $md_key->setKeyword(ilUtil::stripSlashes($k));
2396  $md_key->setKeywordLanguage(new ilMDLanguageItem($lang));
2397  $md_key->save();
2398  }
2399  $mkeywords[] = strtolower($k);
2400  }
2401  }
2402  }
2403  }
2404 
2410  function saveMobUsage($a_xml, $a_old_nr = 0)
2411  {
2412  $doc = domxml_open_mem($a_xml);
2413 
2414  // media aliases
2415  $xpc = xpath_new_context($doc);
2416  $path = "//MediaAlias";
2417  $res =& xpath_eval($xpc, $path);
2418  $usages = array();
2419  for ($i=0; $i < count($res->nodeset); $i++)
2420  {
2421  $id_arr = explode("_", $res->nodeset[$i]->get_attribute("OriginId"));
2422  $mob_id = $id_arr[count($id_arr) - 1];
2423  if ($mob_id > 0)
2424  {
2425  $usages[$mob_id] = true;
2426  }
2427  }
2428 
2429  // media objects
2430  $xpc = xpath_new_context($doc);
2431  $path = "//MediaObject/MetaData/General/Identifier";
2432  $res =& xpath_eval($xpc, $path);
2433  for ($i=0; $i < count($res->nodeset); $i++)
2434  {
2435  $mob_entry = $res->nodeset[$i]->get_attribute("Entry");
2436  $mob_arr = explode("_", $mob_entry);
2437  $mob_id = $mob_arr[count($mob_arr) - 1];
2438  if ($mob_id > 0)
2439  {
2440  $usages[$mob_id] = true;
2441  }
2442  }
2443 
2444  // internal links
2445  $xpc = xpath_new_context($doc);
2446  $path = "//IntLink[@Type='MediaObject']";
2447  $res =& xpath_eval($xpc, $path);
2448  for ($i=0; $i < count($res->nodeset); $i++)
2449  {
2450  $mob_target = $res->nodeset[$i]->get_attribute("Target");
2451  $mob_arr = explode("_", $mob_target);
2452  $mob_id = $mob_arr[count($mob_arr) - 1];
2453  if ($mob_id > 0)
2454  {
2455  $usages[$mob_id] = true;
2456  }
2457  }
2458 
2459  include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
2460  ilObjMediaObject::_deleteAllUsages($this->getParentType().":pg", $this->getId(), $a_old_nr);
2461  foreach($usages as $mob_id => $val)
2462  {
2463  ilObjMediaObject::_saveUsage($mob_id, $this->getParentType().":pg", $this->getId(), $a_old_nr);
2464  }
2465 
2466  return $usages;
2467  }
2468 
2472  function saveFileUsage($a_xml = "", $a_old_nr = 0)
2473  {
2474  $file_ids = $this->collectFileItems($a_xml, $a_old_nr);
2475  include_once("./Modules/File/classes/class.ilObjFile.php");
2476  ilObjFile::_deleteAllUsages($this->getParentType().":pg", $this->getId(), $a_old_nr);
2477  foreach($file_ids as $file_id)
2478  {
2479  ilObjFile::_saveUsage($file_id, $this->getParentType().":pg", $this->getId(), $a_old_nr);
2480  }
2481  }
2482 
2486  function saveContentIncludeUsage($a_xml = "", $a_old_nr = 0)
2487  {
2488  include_once("./Services/COPage/classes/class.ilPageContentUsage.php");
2489  $ci_ids = $this->collectContentIncludes($a_xml);
2490  ilPageContentUsage::deleteAllUsages("incl", $this->getParentType().":pg", $this->getId(), $a_old_nr);
2491  foreach($ci_ids as $ci_id)
2492  {
2493  if ((int) $ci_id["inst_id"] <= 0)
2494  {
2495  ilPageContentUsage::saveUsage("incl", $ci_id["id"], $this->getParentType().":pg", $this->getId(), $a_old_nr);
2496  }
2497  }
2498  }
2499 
2503  function collectContentIncludes($a_xml = "")
2504  {
2505  // determine all media aliases of the page
2506  if ($a_xml == "")
2507  {
2508  $this->buildDom();
2509  $xpc = xpath_new_context($this->dom);
2510  $path = "//ContentInclude";
2511  $res =& xpath_eval($xpc, $path);
2512  }
2513  else
2514  {
2515  $doc = domxml_open_mem($a_xml);
2516  $xpc = xpath_new_context($doc);
2517  $path = "//ContentInclude";
2518  $res =& xpath_eval($xpc, $path);
2519  }
2520  $ci_ids = array();
2521  for($i = 0; $i < count($res->nodeset); $i++)
2522  {
2523  $type = $res->nodeset[$i]->get_attribute("ContentType");
2524  $id = $res->nodeset[$i]->get_attribute("ContentId");
2525  $inst_id = $res->nodeset[$i]->get_attribute("InstId");
2526  $ci_ids[$type.":".$id.":".$inst_id] = array(
2527  "type" => $type, "id" => $id, "inst_id" => $inst_id);
2528  }
2529 
2530  return $ci_ids;
2531  }
2532 
2533 
2539  function saveStyleUsage($a_xml, $a_old_nr = 0)
2540  {
2541  global $ilDB;
2542 
2543  $doc = domxml_open_mem($a_xml);
2544 
2545  // media aliases
2546  $xpc = xpath_new_context($doc);
2547  $path = "//Paragraph | //Section | //MediaAlias | //FileItem".
2548  " | //Table | //TableData | //Tabs | //List";
2549  $res = xpath_eval($xpc, $path);
2550  $usages = array();
2551  for ($i=0; $i < count($res->nodeset); $i++)
2552  {
2553  switch ($res->nodeset[$i]->node_name())
2554  {
2555  case "Paragraph":
2556  $sname = $res->nodeset[$i]->get_attribute("Characteristic");
2557  $stype = "text_block";
2558  $template = 0;
2559  break;
2560 
2561  case "Section":
2562  $sname = $res->nodeset[$i]->get_attribute("Characteristic");
2563  $stype = "section";
2564  $template = 0;
2565  break;
2566 
2567  case "MediaAlias":
2568  $sname = $res->nodeset[$i]->get_attribute("Class");
2569  $stype = "media_cont";
2570  $template = 0;
2571  break;
2572 
2573  case "FileItem":
2574  $sname = $res->nodeset[$i]->get_attribute("Class");
2575  $stype = "flist_li";
2576  $template = 0;
2577  break;
2578 
2579  case "Table":
2580  $sname = $res->nodeset[$i]->get_attribute("Template");
2581  if ($sname == "")
2582  {
2583  $sname = $res->nodeset[$i]->get_attribute("Class");
2584  $stype = "table";
2585  $template = 0;
2586  }
2587  else
2588  {
2589  $stype = "table";
2590  $template = 1;
2591  }
2592  break;
2593 
2594  case "TableData":
2595  $sname = $res->nodeset[$i]->get_attribute("Class");
2596  $stype = "table_cell";
2597  $template = 0;
2598  break;
2599 
2600  case "Tabs":
2601  $sname = $res->nodeset[$i]->get_attribute("Template");
2602  if ($sname != "")
2603  {
2604  if ($res->nodeset[$i]->get_attribute("Type") == "HorizontalAccordion")
2605  {
2606  $stype = "haccordion";
2607  }
2608  if ($res->nodeset[$i]->get_attribute("Type") == "VerticalAccordion")
2609  {
2610  $stype = "vaccordion";
2611  }
2612  }
2613  $template = 1;
2614  break;
2615 
2616  case "List":
2617  $sname = $res->nodeset[$i]->get_attribute("Class");
2618  if ($res->nodeset[$i]->get_attribute("Type") == "Ordered")
2619  {
2620  $stype = "list_o";
2621  }
2622  else
2623  {
2624  $stype = "list_u";
2625  }
2626  $template = 0;
2627  break;
2628  }
2629  if ($sname != "" && $stype != "")
2630  {
2631  $usages[$sname.":".$stype.":".$template] = array("sname" => $sname,
2632  "stype" => $stype, "template" => $template);
2633  }
2634  }
2635 
2636  $ilDB->manipulate("DELETE FROM page_style_usage WHERE ".
2637  " page_id = ".$ilDB->quote($this->getId(), "integer").
2638  " AND page_type = ".$ilDB->quote($this->getParentType(), "text").
2639  " AND page_nr = ".$ilDB->quote($a_old_nr, "integer")
2640  );
2641 
2642  foreach ($usages as $u)
2643  {
2644  $ilDB->manipulate("INSERT INTO page_style_usage ".
2645  "(page_id, page_type, page_nr, template, stype, sname) VALUES (".
2646  $ilDB->quote($this->getId(), "integer").",".
2647  $ilDB->quote($this->getParentType(), "text").",".
2648  $ilDB->quote($a_old_nr, "integer").",".
2649  $ilDB->quote($u["template"], "integer").",".
2650  $ilDB->quote($u["stype"], "text").",".
2651  $ilDB->quote($u["sname"], "text").
2652  ")");
2653  }
2654  }
2655 
2661  {
2662  include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
2663  include_once("./Modules/File/classes/class.ilObjFile.php");
2665  $this->getId());
2667  $this->getId());
2668  $objs = array_merge($mobs, $files);
2669  return ilObject::_getLastUpdateOfObjects($objs);
2670  }
2671 
2677  function saveInternalLinks($a_xml)
2678  {
2679  global $ilDB;
2680 
2681 //echo "<br>PageObject::saveInternalLinks[".$this->getId()."]";
2682  $doc = domxml_open_mem($a_xml);
2683 
2684 
2685  include_once("./Services/COPage/classes/class.ilInternalLink.php");
2687 
2688  // get all internal links
2689  $xpc = xpath_new_context($doc);
2690  $path = "//IntLink";
2691  $res =& xpath_eval($xpc, $path);
2692  for ($i=0; $i < count($res->nodeset); $i++)
2693  {
2694  $link_type = $res->nodeset[$i]->get_attribute("Type");
2695 
2696  switch ($link_type)
2697  {
2698  case "StructureObject":
2699  $t_type = "st";
2700  break;
2701 
2702  case "PageObject":
2703  $t_type = "pg";
2704  break;
2705 
2706  case "GlossaryItem":
2707  $t_type = "git";
2708  break;
2709 
2710  case "MediaObject":
2711  $t_type = "mob";
2712  break;
2713 
2714  case "RepositoryItem":
2715  $t_type = "obj";
2716  break;
2717 
2718  case "File":
2719  $t_type = "file";
2720  break;
2721  }
2722 
2723  $target = $res->nodeset[$i]->get_attribute("Target");
2724  $target_arr = explode("_", $target);
2725  $t_id = $target_arr[count($target_arr) - 1];
2726 
2727  // link to other internal object
2728  if (is_int(strpos($target, "__")))
2729  {
2730  $t_inst = 0;
2731  }
2732  else // link to unresolved object in other installation
2733  {
2734  $t_inst = $target_arr[1];
2735  }
2736 
2737  if ($t_id > 0)
2738  {
2739  ilInternalLink::_saveLink($this->getParentType().":pg", $this->getId(), $t_type,
2740  $t_id, $t_inst);
2741  }
2742  }
2743 
2744  // *** STEP 2: Save question references of page ***
2745 
2746  // delete all reference records
2747  $ilDB->manipulateF("DELETE FROM page_question WHERE page_parent_type = %s ".
2748  " AND page_id = %s", array("text", "integer"),
2749  array($this->getParentType(), $this->getId()));
2750 
2751  // save question references of page
2752  $doc = domxml_open_mem($a_xml);
2753  $xpc = xpath_new_context($doc);
2754  $path = "//Question";
2755  $res = xpath_eval($xpc, $path);
2756  $q_ids = array();
2757  for ($i=0; $i < count($res->nodeset); $i++)
2758  {
2759  $q_ref = $res->nodeset[$i]->get_attribute("QRef");
2760 
2761  $inst_id = ilInternalLink::_extractInstOfTarget($q_ref);
2762  if (!($inst_id > 0))
2763  {
2764  $q_id = ilInternalLink::_extractObjIdOfTarget($q_ref);
2765  if ($q_id > 0)
2766  {
2767  $q_ids[$q_id] = $q_id;
2768  }
2769  }
2770  }
2771  foreach($q_ids as $qid)
2772  {
2773  $ilDB->manipulateF("INSERT INTO page_question (page_parent_type, page_id, question_id)".
2774  " VALUES (%s,%s,%s)",
2775  array("text", "integer", "integer"),
2776  array($this->getParentType(), $this->getId(), $qid));
2777  }
2778  }
2779 
2783  static function _getQuestionIdsForPage($a_parent_type, $a_page_id)
2784  {
2785  global $ilDB;
2786 
2787  $res = $ilDB->queryF("SELECT * FROM page_question WHERE page_parent_type = %s ".
2788  " AND page_id = %s",
2789  array("text", "integer"),
2790  array($a_parent_type, $a_page_id));
2791  $q_ids = array();
2792  while ($rec = $ilDB->fetchAssoc($res))
2793  {
2794  $q_ids[] = $rec["question_id"];
2795  }
2796 
2797  return $q_ids;
2798  }
2799 
2805  function saveAnchors($a_xml)
2806  {
2807  $doc = domxml_open_mem($a_xml);
2808 
2809  ilPageObject::_deleteAnchors($this->getParentType(), $this->getId());
2810 
2811  // get all anchors
2812  $xpc = xpath_new_context($doc);
2813  $path = "//Anchor";
2814  $res =& xpath_eval($xpc, $path);
2815  $saved = array();
2816  for ($i=0; $i < count($res->nodeset); $i++)
2817  {
2818  $name = $res->nodeset[$i]->get_attribute("Name");
2819  if (trim($name) != "" && !in_array($name, $saved))
2820  {
2821  ilPageObject::_saveAnchor($this->getParentType(), $this->getId(), $name);
2822  $saved[] = $name;
2823  }
2824  }
2825 
2826  }
2827 
2831  static function _deleteAnchors($a_parent_type, $a_page_id)
2832  {
2833  global $ilDB;
2834 
2835  $st = $ilDB->prepareManip("DELETE FROM page_anchor WHERE page_parent_type = ? ".
2836  " AND page_id = ?", array("text", "integer"));
2837  $ilDB->execute($st, array($a_parent_type, $a_page_id));
2838  }
2839 
2843  static function _saveAnchor($a_parent_type, $a_page_id, $a_anchor_name)
2844  {
2845  global $ilDB;
2846 
2847  $st = $ilDB->prepareManip("INSERT INTO page_anchor (page_parent_type, page_id, anchor_name) ".
2848  " VALUES (?,?,?) ", array("text", "integer", "text"));
2849  $ilDB->execute($st, array($a_parent_type, $a_page_id, $a_anchor_name));
2850  }
2851 
2855  static function _readAnchors($a_parent_type, $a_page_id)
2856  {
2857  global $ilDB;
2858 
2859  $st = $ilDB->prepare("SELECT * FROM page_anchor WHERE page_parent_type = ? ".
2860  " AND page_id = ?", array("text", "integer"));
2861  $set = $ilDB->execute($st, array($a_parent_type, $a_page_id));
2862  $anchors = array();
2863  while ($rec = $ilDB->fetchAssoc($set))
2864  {
2865  $anchors[] = $rec["anchor_name"];
2866  }
2867  return $anchors;
2868  }
2869 
2873  function create()
2874  {
2875  $this->createFromXML();
2876  }
2877 
2885  function deleteContent($a_hid, $a_update = true, $a_pcid = "")
2886  {
2887  $curr_node =& $this->getContentNode($a_hid, $a_pcid);
2888  $curr_node->unlink_node($curr_node);
2889  if ($a_update)
2890  {
2891  return $this->update();
2892  }
2893  }
2894 
2895 
2903  function deleteContents($a_hids, $a_update = true)
2904  {
2905  if (!is_array($a_hids))
2906  {
2907  return;
2908  }
2909  foreach($a_hids as $a_hid)
2910  {
2911  $a_hid = explode(":", $a_hid);
2912 //echo "-".$a_hid[0]."-".$a_hid[1]."-";
2913  $curr_node =& $this->getContentNode($a_hid[0], $a_hid[1]);
2914  if (is_object($curr_node))
2915  {
2916  $parent_node = $curr_node->parent_node();
2917  if ($parent_node->node_name() != "TableRow")
2918  {
2919  $curr_node->unlink_node($curr_node);
2920  }
2921  }
2922  }
2923  if ($a_update)
2924  {
2925  return $this->update();
2926  }
2927  }
2928 
2934  function cutContents($a_hids)
2935  {
2936  $this->copyContents($a_hids);
2937  return $this->deleteContents($a_hids);
2938  }
2939 
2945  function copyContents($a_hids)
2946  {
2947  global $ilUser;
2948 //var_dump($a_hids);
2949  if (!is_array($a_hids))
2950  {
2951  return;
2952  }
2953 
2954  $time = date("Y-m-d H:i:s", time());
2955 
2956  $hier_ids = array();
2957  $skip = array();
2958  foreach($a_hids as $a_hid)
2959  {
2960  if ($a_hid == "")
2961  {
2962  continue;
2963  }
2964  $a_hid = explode(":", $a_hid);
2965 
2966  // check, whether new hid is child of existing one or vice versa
2967  reset($hier_ids);
2968  foreach($hier_ids as $h)
2969  {
2970  if($h."_" == substr($a_hid[0], 0, strlen($h) + 1))
2971  {
2972  $skip[] = $a_hid[0];
2973  }
2974  if($a_hid[0]."_" == substr($h, 0, strlen($a_hid[0]) + 1))
2975  {
2976  $skip[] = $h;
2977  }
2978  }
2979  $pc_id[$a_hid[0]] = $a_hid[1];
2980  if ($a_hid[0] != "")
2981  {
2982  $hier_ids[$a_hid[0]] = $a_hid[0];
2983  }
2984  }
2985  foreach ($skip as $s)
2986  {
2987  unset($hier_ids[$s]);
2988  }
2989  include_once("./Services/COPage/classes/class.ilPageContent.php");
2990  $hier_ids = ilPageContent::sortHierIds($hier_ids);
2991  $nr = 1;
2992  foreach($hier_ids as $hid)
2993  {
2994  $curr_node = $this->getContentNode($hid, $pc_id[$hid]);
2995  if (is_object($curr_node))
2996  {
2997  if ($curr_node->node_name() == "PageContent")
2998  {
2999  $content = $this->dom->dump_node($curr_node);
3000  // remove pc and hier ids
3001  $content = eregi_replace("PCID=\"[a-z0-9]*\"","",$content);
3002  $content = eregi_replace("HierId=\"[a-z0-9_]*\"","",$content);
3003 
3004  $ilUser->addToPCClipboard($content, $time, $nr);
3005  $nr++;
3006  }
3007  }
3008  }
3009  include_once("./Modules/LearningModule/classes/class.ilEditClipboard.php");
3011  }
3012 
3016  function pasteContents($a_hier_id)
3017  {
3018  global $ilUser;
3019 
3020  $a_hid = explode(":", $a_hier_id);
3021  $content = $ilUser->getPCClipboardContent();
3022 
3023  // we insert from last to first, because we insert all at the
3024  // same hier_id
3025  for ($i = count($content) - 1; $i >= 0; $i--)
3026  {
3027 
3028  $c = $content[$i];
3029  $temp_dom = domxml_open_mem('<?xml version="1.0" encoding="UTF-8"?>'.$c,
3030  DOMXML_LOAD_PARSING, $error);
3031  if(empty($error))
3032  {
3033  $this->newQuestionCopies($temp_dom);
3034  $xpc = xpath_new_context($temp_dom);
3035  $path = "//PageContent";
3036  $res = xpath_eval($xpc, $path);
3037  if (count($res->nodeset) > 0)
3038  {
3039  $new_pc_node = $res->nodeset[0];
3040  $cloned_pc_node = $new_pc_node->clone_node (true);
3041  $cloned_pc_node->unlink_node ($cloned_pc_node);
3042  $this->insertContentNode ($cloned_pc_node, $a_hid[0],
3043  IL_INSERT_AFTER, $a_hid[1]);
3044  }
3045  }
3046  else
3047  {
3048 //var_dump($error);
3049  }
3050  }
3051  $e = $this->update();
3052 //var_dump($e);
3053  }
3054 
3059  function switchEnableMultiple($a_hids, $a_update = true)
3060  {
3061  if (!is_array($a_hids))
3062  {
3063  return;
3064  }
3065  $obj = & $this->content_obj;
3066 
3067  foreach($a_hids as $a_hid)
3068  {
3069  $a_hid = explode(":", $a_hid);
3070 //echo "-".$a_hid[0]."-".$a_hid[1]."-";
3071  $curr_node =& $this->getContentNode($a_hid[0], $a_hid[1]);
3072  if (is_object($curr_node))
3073  {
3074  if ($curr_node->node_name() == "PageContent")
3075  {
3076  $cont_obj =& $this->getContentObject($a_hid[0], $a_hid[1]);
3077  if ($cont_obj->isEnabled ())
3078  $cont_obj->disable ();
3079  else
3080  $cont_obj->enable ();
3081  }
3082  }
3083  }
3084 
3085  if ($a_update)
3086  {
3087  return $this->update();
3088  }
3089  }
3090 
3091 
3099  function deleteContentFromHierId($a_hid, $a_update = true)
3100  {
3101  $hier_ids = $this->getHierIds();
3102 
3103  // iterate all hierarchical ids
3104  foreach ($hier_ids as $hier_id)
3105  {
3106  // delete top level nodes only
3107  if (!is_int(strpos($hier_id, "_")))
3108  {
3109  if ($hier_id != "pg" && $hier_id >= $a_hid)
3110  {
3111  $curr_node =& $this->getContentNode($hier_id);
3112  $curr_node->unlink_node($curr_node);
3113  }
3114  }
3115  }
3116  if ($a_update)
3117  {
3118  return $this->update();
3119  }
3120  }
3121 
3129  function deleteContentBeforeHierId($a_hid, $a_update = true)
3130  {
3131  $hier_ids = $this->getHierIds();
3132 
3133  // iterate all hierarchical ids
3134  foreach ($hier_ids as $hier_id)
3135  {
3136  // delete top level nodes only
3137  if (!is_int(strpos($hier_id, "_")))
3138  {
3139  if ($hier_id != "pg" && $hier_id < $a_hid)
3140  {
3141  $curr_node =& $this->getContentNode($hier_id);
3142  $curr_node->unlink_node($curr_node);
3143  }
3144  }
3145  }
3146  if ($a_update)
3147  {
3148  return $this->update();
3149  }
3150  }
3151 
3152 
3160  function _moveContentAfterHierId(&$a_source_page, &$a_target_page, $a_hid)
3161  {
3162  $hier_ids = $a_source_page->getHierIds();
3163 
3164  $copy_ids = array();
3165 
3166  // iterate all hierarchical ids
3167  foreach ($hier_ids as $hier_id)
3168  {
3169  // move top level nodes only
3170  if (!is_int(strpos($hier_id, "_")))
3171  {
3172  if ($hier_id != "pg" && $hier_id >= $a_hid)
3173  {
3174  $copy_ids[] = $hier_id;
3175  }
3176  }
3177  }
3178  asort($copy_ids);
3179 
3180  $parent_node =& $a_target_page->getContentNode("pg");
3181  $target_dom =& $a_target_page->getDom();
3182  $parent_childs =& $parent_node->child_nodes();
3183  $cnt_parent_childs = count($parent_childs);
3184 //echo "-$cnt_parent_childs-";
3185  $first_child =& $parent_childs[0];
3186  foreach($copy_ids as $copy_id)
3187  {
3188  $source_node =& $a_source_page->getContentNode($copy_id);
3189 
3190  $new_node =& $source_node->clone_node(true);
3191  $new_node->unlink_node($new_node);
3192 
3193  $source_node->unlink_node($source_node);
3194 
3195  if($cnt_parent_childs == 0)
3196  {
3197  $new_node =& $parent_node->append_child($new_node);
3198  }
3199  else
3200  {
3201  //$target_dom->import_node($new_node);
3202  $new_node =& $first_child->insert_before($new_node, $first_child);
3203  }
3204  $parent_childs =& $parent_node->child_nodes();
3205 
3206  //$cnt_parent_childs++;
3207  }
3208 
3209  $a_target_page->update();
3210  $a_source_page->update();
3211 
3212  }
3213 
3217  function insertContent(&$a_cont_obj, $a_pos, $a_mode = IL_INSERT_AFTER, $a_pcid = "")
3218  {
3219  // move mode into container elements is always INSERT_CHILD
3220  $curr_node = $this->getContentNode($a_pos, $a_pcid);
3221  $curr_name = $curr_node->node_name();
3222  if (($curr_name == "TableData") || ($curr_name == "PageObject") ||
3223  ($curr_name == "ListItem") || ($curr_name == "Section")
3224  || ($curr_name == "Tab"))
3225  {
3226  $a_mode = IL_INSERT_CHILD;
3227  }
3228 
3229  $hid = $curr_node->get_attribute("HierId");
3230  if ($hid != "")
3231  {
3232 //echo "-".$a_pos."-".$hid."-";
3233  $a_pos = $hid;
3234  }
3235 
3236  if($a_mode != IL_INSERT_CHILD) // determine parent hierarchical id
3237  { // of sibling at $a_pos
3238  $pos = explode("_", $a_pos);
3239  $target_pos = array_pop($pos);
3240  $parent_pos = implode($pos, "_");
3241  }
3242  else // if we should insert a child, $a_pos is alreade the hierarchical id
3243  { // of the parent node
3244  $parent_pos = $a_pos;
3245  }
3246 
3247  // get the parent node
3248  if($parent_pos != "")
3249  {
3250  $parent_node =& $this->getContentNode($parent_pos);
3251  }
3252  else
3253  {
3254  $parent_node =& $this->getNode();
3255  }
3256 
3257  // count the parent children
3258  $parent_childs =& $parent_node->child_nodes();
3259  $cnt_parent_childs = count($parent_childs);
3260 //echo "ZZ$a_mode";
3261  switch ($a_mode)
3262  {
3263  // insert new node after sibling at $a_pos
3264  case IL_INSERT_AFTER:
3265  $new_node =& $a_cont_obj->getNode();
3266  //$a_pos = ilPageContent::incEdId($a_pos);
3267  //$curr_node =& $this->getContentNode($a_pos);
3268 //echo "behind $a_pos:";
3269  if($succ_node =& $curr_node->next_sibling())
3270  {
3271  $new_node =& $succ_node->insert_before($new_node, $succ_node);
3272  }
3273  else
3274  {
3275 //echo "movin doin append_child";
3276  $new_node =& $parent_node->append_child($new_node);
3277  }
3278  $a_cont_obj->setNode($new_node);
3279  break;
3280 
3281  case IL_INSERT_BEFORE:
3282 //echo "INSERT_BEF";
3283  $new_node =& $a_cont_obj->getNode();
3284  $succ_node =& $this->getContentNode($a_pos);
3285  $new_node =& $succ_node->insert_before($new_node, $succ_node);
3286  $a_cont_obj->setNode($new_node);
3287  break;
3288 
3289  // insert new node as first child of parent $a_pos (= $a_parent)
3290  case IL_INSERT_CHILD:
3291 //echo "insert as child:parent_childs:$cnt_parent_childs:<br>";
3292  $new_node =& $a_cont_obj->getNode();
3293  if($cnt_parent_childs == 0)
3294  {
3295  $new_node =& $parent_node->append_child($new_node);
3296  }
3297  else
3298  {
3299  $new_node =& $parent_childs[0]->insert_before($new_node, $parent_childs[0]);
3300  }
3301  $a_cont_obj->setNode($new_node);
3302 //echo "PP";
3303  break;
3304  }
3305 
3306  //check for PlaceHolder to remove in EditMode-keep in Layout Mode
3307  if (!$this->getLayoutMode()) {
3308  $sub_nodes = $curr_node->child_nodes() ;
3309  foreach ( $sub_nodes as $sub_node ) {
3310  if ($sub_node->node_name() == "PlaceHolder") {
3311  $curr_node->unlink_node();
3312  }
3313  }
3314  }
3315  }
3316 
3320  function insertContentNode(&$a_cont_node, $a_pos, $a_mode = IL_INSERT_AFTER, $a_pcid = "")
3321  {
3322  // move mode into container elements is always INSERT_CHILD
3323  $curr_node = $this->getContentNode($a_pos, $a_pcid);
3324  $curr_name = $curr_node->node_name();
3325  if (($curr_name == "TableData") || ($curr_name == "PageObject") ||
3326  ($curr_name == "ListItem") || ($curr_name == "Section")
3327  || ($curr_name == "Tab"))
3328  {
3329  $a_mode = IL_INSERT_CHILD;
3330  }
3331 
3332  $hid = $curr_node->get_attribute("HierId");
3333  if ($hid != "")
3334  {
3335  $a_pos = $hid;
3336  }
3337 
3338  if($a_mode != IL_INSERT_CHILD) // determine parent hierarchical id
3339  { // of sibling at $a_pos
3340  $pos = explode("_", $a_pos);
3341  $target_pos = array_pop($pos);
3342  $parent_pos = implode($pos, "_");
3343  }
3344  else // if we should insert a child, $a_pos is alreade the hierarchical id
3345  { // of the parent node
3346  $parent_pos = $a_pos;
3347  }
3348 
3349  // get the parent node
3350  if($parent_pos != "")
3351  {
3352  $parent_node =& $this->getContentNode($parent_pos);
3353  }
3354  else
3355  {
3356  $parent_node =& $this->getNode();
3357  }
3358 
3359  // count the parent children
3360  $parent_childs =& $parent_node->child_nodes();
3361  $cnt_parent_childs = count($parent_childs);
3362 
3363  switch ($a_mode)
3364  {
3365  // insert new node after sibling at $a_pos
3366  case IL_INSERT_AFTER:
3367  //$new_node =& $a_cont_obj->getNode();
3368  if($succ_node = $curr_node->next_sibling())
3369  {
3370  $a_cont_node = $succ_node->insert_before($a_cont_node, $succ_node);
3371  }
3372  else
3373  {
3374  $a_cont_node = $parent_node->append_child($a_cont_node);
3375  }
3376  //$a_cont_obj->setNode($new_node);
3377  break;
3378 
3379  case IL_INSERT_BEFORE:
3380  //$new_node =& $a_cont_obj->getNode();
3381  $succ_node = $this->getContentNode($a_pos);
3382  $a_cont_node = $succ_node->insert_before($a_cont_node, $succ_node);
3383  //$a_cont_obj->setNode($new_node);
3384  break;
3385 
3386  // insert new node as first child of parent $a_pos (= $a_parent)
3387  case IL_INSERT_CHILD:
3388  //$new_node =& $a_cont_obj->getNode();
3389  if($cnt_parent_childs == 0)
3390  {
3391  $a_cont_node = $parent_node->append_child($a_cont_node);
3392  }
3393  else
3394  {
3395  $a_cont_node = $parent_childs[0]->insert_before($a_cont_node, $parent_childs[0]);
3396  }
3397  //$a_cont_obj->setNode($new_node);
3398  break;
3399  }
3400  }
3401 
3406  function moveContentBefore($a_source, $a_target, $a_spcid = "", $a_tpcid = "")
3407  {
3408  if($a_source == $a_target)
3409  {
3410  return;
3411  }
3412 
3413  // clone the node
3414  $content =& $this->getContentObject($a_source, $a_spcid);
3415  $source_node =& $content->getNode();
3416  $clone_node =& $source_node->clone_node(true);
3417 
3418  // delete source node
3419  $this->deleteContent($a_source, false, $a_spcid);
3420 
3421  // insert cloned node at target
3422  $content->setNode($clone_node);
3423  $this->insertContent($content, $a_target, IL_INSERT_BEFORE, $a_tpcid);
3424  return $this->update();
3425 
3426  }
3427 
3432  function moveContentAfter($a_source, $a_target, $a_spcid = "", $a_tpcid = "")
3433  {
3434  if($a_source == $a_target)
3435  {
3436  return;
3437  }
3438 
3439  // clone the node
3440  $content =& $this->getContentObject($a_source, $a_spcid);
3441  $source_node =& $content->getNode();
3442  $clone_node =& $source_node->clone_node(true);
3443 
3444  // delete source node
3445  $this->deleteContent($a_source, false, $a_spcid);
3446 
3447  // insert cloned node at target
3448  $content->setNode($clone_node);
3449  $this->insertContent($content, $a_target, IL_INSERT_AFTER, $a_tpcid);
3450  return $this->update();
3451  }
3452 
3456  function bbCode2XML(&$a_content)
3457  {
3458  $a_content = eregi_replace("\[com\]","<Comment>",$a_content);
3459  $a_content = eregi_replace("\[\/com\]","</Comment>",$a_content);
3460  $a_content = eregi_replace("\[emp]","<Emph>",$a_content);
3461  $a_content = eregi_replace("\[\/emp\]","</Emph>",$a_content);
3462  $a_content = eregi_replace("\[str]","<Strong>",$a_content);
3463  $a_content = eregi_replace("\[\/str\]","</Strong>",$a_content);
3464  }
3465 
3470  function insertInstIntoIDs($a_inst, $a_res_ref_to_obj_id = true)
3471  {
3472  // insert inst id into internal links
3473  $xpc = xpath_new_context($this->dom);
3474  $path = "//IntLink";
3475  $res =& xpath_eval($xpc, $path);
3476  for($i = 0; $i < count($res->nodeset); $i++)
3477  {
3478  $target = $res->nodeset[$i]->get_attribute("Target");
3479  $type = $res->nodeset[$i]->get_attribute("Type");
3480 
3481  if (substr($target, 0, 4) == "il__")
3482  {
3483  $id = substr($target, 4, strlen($target) - 4);
3484 
3485  // convert repository links obj_<ref_id> to <type>_<obj_id>
3486  if ($a_res_ref_to_obj_id && $type == "RepositoryItem")
3487  {
3488  $id_arr = explode("_", $id);
3489  $obj_id = ilObject::_lookupObjId($id_arr[1]);
3490  $otype = ilObject::_lookupType($obj_id);
3491  if ($obj_id > 0)
3492  {
3493  $id = $otype."_".$obj_id;
3494  }
3495  }
3496  $new_target = "il_".$a_inst."_".$id;
3497  $res->nodeset[$i]->set_attribute("Target", $new_target);
3498  }
3499  }
3500  unset($xpc);
3501 
3502  // insert inst id into media aliases
3503  $xpc = xpath_new_context($this->dom);
3504  $path = "//MediaAlias";
3505  $res =& xpath_eval($xpc, $path);
3506  for($i = 0; $i < count($res->nodeset); $i++)
3507  {
3508  $origin_id = $res->nodeset[$i]->get_attribute("OriginId");
3509  if (substr($origin_id, 0, 4) == "il__")
3510  {
3511  $new_id = "il_".$a_inst."_".substr($origin_id, 4, strlen($origin_id) - 4);
3512  $res->nodeset[$i]->set_attribute("OriginId", $new_id);
3513  }
3514  }
3515  unset($xpc);
3516 
3517  // insert inst id file item identifier entries
3518  $xpc = xpath_new_context($this->dom);
3519  $path = "//FileItem/Identifier";
3520  $res =& xpath_eval($xpc, $path);
3521  for($i = 0; $i < count($res->nodeset); $i++)
3522  {
3523  $origin_id = $res->nodeset[$i]->get_attribute("Entry");
3524  if (substr($origin_id, 0, 4) == "il__")
3525  {
3526  $new_id = "il_".$a_inst."_".substr($origin_id, 4, strlen($origin_id) - 4);
3527  $res->nodeset[$i]->set_attribute("Entry", $new_id);
3528  }
3529  }
3530  unset($xpc);
3531 
3532  // insert inst id into question references
3533  $xpc = xpath_new_context($this->dom);
3534  $path = "//Question";
3535  $res =& xpath_eval($xpc, $path);
3536  for($i = 0; $i < count($res->nodeset); $i++)
3537  {
3538  $qref = $res->nodeset[$i]->get_attribute("QRef");
3539 //echo "<br>setted:".$qref;
3540  if (substr($qref, 0, 4) == "il__")
3541  {
3542  $new_id = "il_".$a_inst."_".substr($qref, 4, strlen($qref) - 4);
3543 //echo "<br>setting:".$new_id;
3544  $res->nodeset[$i]->set_attribute("QRef", $new_id);
3545  }
3546  }
3547  unset($xpc);
3548 
3549  }
3550 
3555  function highlightText($a_text, $proglang, $autoindent)
3556  {
3557 
3558  if (!$this->hasHighlighter($proglang)) {
3559  $proglang="plain";
3560  }
3561 
3562  require_once("./Services/COPage/syntax_highlight/php/HFile/HFile_".$proglang.".php");
3563  $classname = "HFile_$proglang";
3564  $h_instance = new $classname();
3565  if ($autoindent == "n") {
3566  $h_instance ->notrim = 1;
3567  $h_instance ->indent = array ("");
3568  $h_instance ->unindent = array ("");
3569  }
3570 
3571  $highlighter = new Core($h_instance, new Output_css());
3572  $a_text = $highlighter->highlight_text(html_entity_decode($a_text));
3573 
3574  return $a_text;
3575  }
3576 
3577  function hasHighlighter ($hfile_ext) {
3578  return file_exists ("Services/COPage/syntax_highlight/php/HFile/HFile_".$hfile_ext.".php");
3579  }
3580 
3586  function insertSourceCodeParagraphs($a_output, $outputmode = "presentation")
3587  {
3588  $xpc = xpath_new_context($this->dom);
3589  $path = "//Paragraph"; //"[@Characteristic = 'Code']";
3590  $res = & xpath_eval($xpc, $path);
3591  for($i = 0; $i < count($res->nodeset); $i++)
3592  {
3593  $context_node = $res->nodeset[$i];
3594  $char = $context_node->get_attribute('Characteristic');
3595 
3596  if ($char != "Code")
3597  continue;
3598 
3599  $n = $context_node->parent_node();
3600  $char = $context_node->get_attribute('Characteristic');
3601  $subchar = $context_node->get_attribute('SubCharacteristic');
3602  $showlinenumbers = $context_node->get_attribute('ShowLineNumbers');
3603  $downloadtitle = $context_node->get_attribute('DownloadTitle');
3604  $autoindent = $context_node->get_attribute('AutoIndent');
3605 
3606  $content = "";
3607 
3608  // get XML Content
3609  $childs = $context_node->child_nodes();
3610 
3611  for($j=0; $j<count($childs); $j++)
3612  {
3613  $content .= $this->dom->dump_node($childs[$j]);
3614  }
3615 
3616  while ($context_node->has_child_nodes ())
3617  {
3618  $node_del = $context_node->first_child ();
3619  $context_node->remove_child ($node_del);
3620  }
3621 
3622  $content = str_replace("<br />", "<br/>", utf8_decode($content) );
3623  $content = str_replace("<br/>", "\n", $content);
3624  $rownums = count(split ("\n",$content));
3625 
3626  $plain_content = html_entity_decode($content);
3627  $plain_content = preg_replace ("/\&#x([1-9a-f]{2});?/ise","chr (base_convert (\\1, 16, 10))",$plain_content);
3628  $plain_content = preg_replace ("/\&#(\d+);?/ise","chr (\\1)",$plain_content);
3629  $content = utf8_encode($this->highlightText($plain_content, $subchar, $autoindent));
3630 
3631  $content = str_replace("&amp;lt;", "&lt;", $content);
3632  $content = str_replace("&amp;gt;", "&gt;", $content);
3633 // $content = str_replace("&", "&amp;", $content);
3634 //var_dump($content);
3635  $rows = "<tr valign=\"top\">";
3636  $rownumbers = "";
3637  $linenumbers= "";
3638 
3639  //if we have to show line numbers
3640  if (strcmp($showlinenumbers,"y")==0)
3641  {
3642  $linenumbers = "<td nowrap=\"nowrap\" class=\"ilc_LineNumbers\" >";
3643  $linenumbers .= "<pre class=\"ilc_Code\">";
3644 
3645  for ($j=0; $j < $rownums; $j++)
3646  {
3647  $indentno = strlen($rownums) - strlen($j+1) + 2;
3648  $rownumeration = ($j+1);
3649  $linenumbers .= "<span class=\"ilc_LineNumber\">$rownumeration</span>";
3650  if ($j < $rownums-1)
3651  {
3652  $linenumbers .= "\n";
3653  }
3654  }
3655  $linenumbers .= "</pre>";
3656  $linenumbers .= "</td>";
3657  }
3658 
3659  $rows .= $linenumbers."<td class=\"ilc_Sourcecode\"><pre class=\"ilc_Code\">".$content."</pre></td>";
3660  $rows .= "</tr>";
3661 
3662  // fix for ie explorer which is not able to produce empty line feeds with <br /><br />;
3663  // workaround: add a space after each br.
3664  $newcontent = str_replace("\n", "<br/>",$rows);
3665  // fix for IE
3666  $newcontent = str_replace("<br/><br/>", "<br/> <br/>",$newcontent);
3667  // falls drei hintereinander...
3668  $newcontent = str_replace("<br/><br/>", "<br/> <br/>",$newcontent);
3669 
3670  // workaround for preventing template engine
3671  // from hiding paragraph text that is enclosed
3672  // in curly brackets (e.g. "{a}", see ilLMEditorGUI::executeCommand())
3673  $newcontent = str_replace("{", "&#123;", $newcontent);
3674  $newcontent = str_replace("}", "&#125;", $newcontent);
3675 
3676 //echo htmlentities($newcontent);
3677  $a_output = str_replace("[[[[[Code;".($i + 1)."]]]]]", $newcontent, $a_output);
3678 
3679  if ($outputmode != "presentation" && is_object($this->offline_handler)
3680  && trim($downloadtitle) != "")
3681  {
3682  // call code handler for offline versions
3683  $this->offline_handler->handleCodeParagraph ($this->id, $i + 1, $downloadtitle, $plain_content);
3684  }
3685  }
3686 
3687  return $a_output;
3688  }
3689 
3690 
3694  function checkPCIds()
3695  {
3696  $this->builddom();
3697  $mydom = $this->dom;
3698 
3699  $sep = $path = "";
3700  foreach ($this->id_elements as $el)
3701  {
3702  $path.= $sep."//".$el."[not(@PCID)]";
3703  $sep = " | ";
3704  }
3705 
3706  $xpc = xpath_new_context($mydom);
3707  $res = & xpath_eval($xpc, $path);
3708 
3709  if (count ($res->nodeset) > 0)
3710  {
3711  return false;
3712  }
3713  return true;
3714  }
3715 
3719  function insertPCIds()
3720  {
3721  $this->builddom();
3722  $mydom = $this->dom;
3723 
3724  $pcids = array();
3725 
3726  $sep = $path = "";
3727  foreach ($this->id_elements as $el)
3728  {
3729  $path.= $sep."//".$el."[@PCID]";
3730  $sep = " | ";
3731  }
3732 
3733  // get existing ids
3734  $xpc = xpath_new_context($mydom);
3735  $res = & xpath_eval($xpc, $path);
3736 
3737  for ($i = 0; $i < count ($res->nodeset); $i++)
3738  {
3739  $node = $res->nodeset[$i];
3740  $pcids[] = $node->get_attribute("PCID");
3741  }
3742 
3743  // add missing ones
3744  $sep = $path = "";
3745  foreach ($this->id_elements as $el)
3746  {
3747  $path.= $sep."//".$el."[not(@PCID)]";
3748  $sep = " | ";
3749  }
3750  $xpc = xpath_new_context($mydom);
3751  $res = & xpath_eval($xpc, $path);
3752 
3753  for ($i = 0; $i < count ($res->nodeset); $i++)
3754  {
3755  $node = $res->nodeset[$i];
3756  $id = ilUtil::randomHash(10, $pcids);
3757  $pcids[] = $id;
3758 //echo "setting-".$id."-";
3759  $res->nodeset[$i]->set_attribute("PCID", $id);
3760  }
3761  }
3762 
3767  {
3768  $this->builddom();
3769  $this->addHierIds();
3770  $mydom = $this->dom;
3771 
3772  // get existing ids
3773  $path = "//PageContent";
3774  $xpc = xpath_new_context($mydom);
3775  $res = & xpath_eval($xpc, $path);
3776 
3777  $hashes = array();
3778  require_once("./Services/COPage/classes/class.ilPCParagraph.php");
3779  for ($i = 0; $i < count ($res->nodeset); $i++)
3780  {
3781  $hier_id = $res->nodeset[$i]->get_attribute("HierId");
3782  $pc_id = $res->nodeset[$i]->get_attribute("PCID");
3783  $dump = $mydom->dump_node($res->nodeset[$i]);
3784  if (($hpos = strpos($dump, ' HierId="'.$hier_id.'"')) > 0)
3785  {
3786  $dump = substr($dump, 0, $hpos).
3787  substr($dump, $hpos + strlen(' HierId="'.$hier_id.'"'));
3788  }
3789 
3790  $childs = $res->nodeset[$i]->child_nodes();
3791  $content = "";
3792  if ($childs[0] && $childs[0]->node_name() == "Paragraph")
3793  {
3794  $content = $mydom->dump_node($childs[0]);
3795  $content = substr($content, strpos($content, ">") + 1,
3796  strrpos($content, "<") - (strpos($content, ">") + 1));
3797 //var_dump($content);
3798  $content = ilPCParagraph::xml2output($content);
3799 //var_dump($content);
3800  }
3801  //$hashes[$hier_id] =
3802  // array("PCID" => $pc_id, "hash" => md5($dump));
3803  $hashes[$pc_id] =
3804  array("hier_id" => $hier_id, "hash" => md5($dump), "content" => $content);
3805  }
3806 
3807  return $hashes;
3808  }
3809 
3813  function getQuestionIds()
3814  {
3815  $this->builddom();
3816  $mydom = $this->dom;
3817 
3818  // Get question IDs
3819  $path = "//Question";
3820  $xpc = xpath_new_context($mydom);
3821  $res = & xpath_eval($xpc, $path);
3822 
3823  $q_ids = array();
3824  include_once("./Services/COPage/classes/class.ilInternalLink.php");
3825  for ($i = 0; $i < count ($res->nodeset); $i++)
3826  {
3827  $qref = $res->nodeset[$i]->get_attribute("QRef");
3828 
3829  $inst_id = ilInternalLink::_extractInstOfTarget($qref);
3830  $obj_id = ilInternalLink::_extractObjIdOfTarget($qref);
3831 
3832  if (!($inst_id > 0))
3833  {
3834  if ($obj_id > 0)
3835  {
3836  $q_ids[] = $obj_id;
3837  }
3838  }
3839  }
3840  return $q_ids;
3841  }
3842 
3843  function send_paragraph ($par_id, $filename)
3844  {
3845  $this->builddom();
3846 
3847  $mydom = $this->dom;
3848 
3849  $xpc = xpath_new_context($mydom);
3850 
3851  //$path = "//PageContent[position () = $par_id]/Paragraph";
3852  //$path = "//Paragraph[$par_id]";
3853  $path = "/descendant::Paragraph[position() = $par_id]";
3854 
3855  $res = & xpath_eval($xpc, $path);
3856 
3857  if (count ($res->nodeset) != 1)
3858  die ("Should not happen");
3859 
3860  $context_node = $res->nodeset[0];
3861 
3862  // get plain text
3863 
3864  $childs = $context_node->child_nodes();
3865 
3866  for($j=0; $j<count($childs); $j++)
3867  {
3868  $content .= $mydom->dump_node($childs[$j]);
3869  }
3870 
3871  $content = str_replace("<br />", "\n", $content);
3872  $content = str_replace("<br/>", "\n", $content);
3873 
3874  $plain_content = html_entity_decode($content);
3875 
3876  ilUtil::deliverData($plain_content, $filename);
3877  /*
3878  $file_type = "application/octet-stream";
3879  header("Content-type: ".$file_type);
3880  header("Content-disposition: attachment; filename=\"$filename\"");
3881  echo $plain_content;*/
3882  exit();
3883  }
3884 
3888  function getFO()
3889  {
3890  $xml = $this->getXMLFromDom(false, true, true);
3891  $xsl = file_get_contents("./Services/COPage/xsl/page_fo.xsl");
3892  $args = array( '/_xml' => $xml, '/_xsl' => $xsl );
3893  $xh = xslt_create();
3894 
3895  $params = array ();
3896 
3897 
3898  $fo = xslt_process($xh,"arg:/_xml","arg:/_xsl",NULL,$args, $params);
3899  var_dump($fo);
3900  // do some replacements
3901  $fo = str_replace("\n", "", $fo);
3902  $fo = str_replace("<br/>", "<br>", $fo);
3903  $fo = str_replace("<br>", "\n", $fo);
3904 
3905  xslt_free($xh);
3906 
3907  //
3908  $fo = substr($fo, strpos($fo,">") + 1);
3909 //echo "<br><b>fo:</b><br>".htmlentities($fo); flush();
3910  return $fo;
3911  }
3912 
3913  function registerOfflineHandler ($handler) {
3914  $this->offline_handler = $handler;
3915  }
3916 
3920  function _lookupContainsDeactivatedElements($a_id, $a_parent_type)
3921  {
3922  global $ilDB;
3923 
3924  /*$query = "SELECT * FROM page_object WHERE page_id = ".
3925  $ilDB->quote($a_id)." AND ".
3926  " parent_type = ".$ilDB->quote($a_parent_type)." AND ".
3927  " content LIKE '% Enabled=\"False\"%'";*/
3928  $query = "SELECT * FROM page_object WHERE page_id = ".
3929  $ilDB->quote($a_id, "integer")." AND ".
3930  " parent_type = ".$ilDB->quote($a_parent_type, "text")." AND ".
3931  " inactive_elements = ".$ilDB->quote(1, "integer");
3932  $obj_set = $ilDB->query($query);
3933 
3934  if ($obj_rec = $obj_set->fetchRow(DB_FETCHMODE_ASSOC))
3935  {
3936  return true;
3937  }
3938 
3939  return false;
3940  }
3941 
3948  function containsDeactivatedElements($a_content)
3949  {
3950  if (strpos($a_content, " Enabled=\"False\""))
3951  {
3952  return true;
3953  }
3954  return false;
3955  }
3956 
3961  {
3962  global $ilDB;
3963 
3964  $h_query = "SELECT * FROM page_history ".
3965  " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
3966  " AND parent_type = ".$ilDB->quote($this->getParentType(), "text").
3967  " ORDER BY hdate DESC";
3968 
3969  $hset = $ilDB->query($h_query);
3970  $hentries = array();
3971 
3972  while ($hrec = $ilDB->fetchAssoc($hset))
3973  {
3974  $hrec["sortkey"] = (int) $hrec["nr"];
3975  $hrec["user"] = (int) $hrec["user_id"];
3976  $hentries[] = $hrec;
3977  }
3978 //var_dump($hentries);
3979  return $hentries;
3980  }
3981 
3985  function getHistoryEntry($a_old_nr)
3986  {
3987  global $ilDB;
3988 
3989  $res = $ilDB->queryF("SELECT * FROM page_history ".
3990  " WHERE page_id = %s ".
3991  " AND parent_type = %s ".
3992  " AND nr = %s",
3993  array("integer", "text", "integer"),
3994  array($this->getId(), $this->getParentType(), $a_old_nr));
3995  if ($hrec = $ilDB->fetchAssoc($res))
3996  {
3997  return $hrec;
3998  }
3999 
4000  return false;
4001  }
4002 
4003 
4010  function getHistoryInfo($a_nr)
4011  {
4012  global $ilDB;
4013 
4014  // determine previous entry
4015  $res = $ilDB->query("SELECT MAX(nr) mnr FROM page_history ".
4016  " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
4017  " AND parent_type = ".$ilDB->quote($this->getParentType(), "text").
4018  " AND nr < ".$ilDB->quote((int) $a_nr, "integer"));
4019  $row = $ilDB->fetchAssoc($res);
4020  if ($row["mnr"] > 0)
4021  {
4022  $res = $ilDB->query("SELECT * FROM page_history ".
4023  " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
4024  " AND parent_type = ".$ilDB->quote($this->getParentType(), "text").
4025  " AND nr = ".$ilDB->quote((int) $row["mnr"], "integer"));
4026  $row = $ilDB->fetchAssoc($res);
4027  $ret["previous"] = $row;
4028  }
4029 
4030  // determine next entry
4031  $res = $ilDB->query("SELECT MIN(nr) mnr FROM page_history ".
4032  " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
4033  " AND parent_type = ".$ilDB->quote($this->getParentType(), "text").
4034  " AND nr > ".$ilDB->quote((int) $a_nr, "integer"));
4035  $row = $ilDB->fetchAssoc($res);
4036  if ($row["mnr"] > 0)
4037  {
4038  $res = $ilDB->query("SELECT * FROM page_history ".
4039  " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
4040  " AND parent_type = ".$ilDB->quote($this->getParentType(), "text").
4041  " AND nr = ".$ilDB->quote((int) $row["mnr"], "integer"));
4042  $row = $ilDB->fetchAssoc($res);
4043  $ret["next"] = $row;
4044  }
4045 
4046  // current
4047  $res = $ilDB->query("SELECT * FROM page_history ".
4048  " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
4049  " AND parent_type = ".$ilDB->quote($this->getParentType(), "text").
4050  " AND nr = ".$ilDB->quote((int) $a_nr, "integer"));
4051  $row = $ilDB->fetchAssoc($res);
4052  $ret["current"] = $row;
4053 
4054  return $ret;
4055  }
4056 
4057  function addChangeDivClasses($a_hashes)
4058  {
4059  $xpc = xpath_new_context($this->dom);
4060  $path = "/*[1]";
4061  $res =& xpath_eval($xpc, $path);
4062  $rnode = $res->nodeset[0];
4063 
4064 //echo "A";
4065  foreach($a_hashes as $pc_id => $h)
4066  {
4067 //echo "B";
4068  if ($h["change"] != "")
4069  {
4070 //echo "<br>C-".$h["hier_id"]."-".$h["change"]."-";
4071  $dc_node = $this->dom->create_element("DivClass");
4072  $dc_node->set_attribute("HierId", $h["hier_id"]);
4073  $dc_node->set_attribute("Class", "ilEdit".$h["change"]);
4074  $dc_node = $rnode->append_child($dc_node);
4075  }
4076  }
4077  }
4078 
4085  function compareVersion($a_left, $a_right)
4086  {
4087  global $ilDB;
4088 
4089  // get page objects
4090  $l_page = new ilPageObject($this->getParentType(), $this->getId(), $a_left);
4091  $r_page = new ilPageObject($this->getParentType(), $this->getId(), $a_right);
4092 
4093  $l_hashes = $l_page->getPageContentsHashes();
4094  $r_hashes = $r_page->getPageContentsHashes();
4095 
4096  // determine all deleted and changed page elements
4097  foreach ($l_hashes as $pc_id => $h)
4098  {
4099  if (!isset($r_hashes[$pc_id]))
4100  {
4101  $l_hashes[$pc_id]["change"] = "Deleted";
4102  }
4103  else
4104  {
4105  if ($l_hashes[$pc_id]["hash"] != $r_hashes[$pc_id]["hash"])
4106  {
4107  $l_hashes[$pc_id]["change"] = "Modified";
4108  $r_hashes[$pc_id]["change"] = "Modified";
4109 
4110  include_once("./Services/COPage/mediawikidiff/class.WordLevelDiff.php");
4111  // if modified element is a paragraph, highlight changes
4112  if ($l_hashes[$pc_id]["content"] != "" &&
4113  $r_hashes[$pc_id]["content"] != "")
4114  {
4115  $new_left = str_replace("\n", "<br />", $l_hashes[$pc_id]["content"]);
4116  $new_right = str_replace("\n", "<br />", $r_hashes[$pc_id]["content"]);
4117  $wldiff = new WordLevelDiff(array($new_left),
4118  array($new_right));
4119  $new_left = $wldiff->orig();
4120  $new_right = $wldiff->closing();
4121  $l_page->setParagraphContent($l_hashes[$pc_id]["hier_id"], $new_left[0]);
4122  $r_page->setParagraphContent($l_hashes[$pc_id]["hier_id"], $new_right[0]);
4123  }
4124  }
4125  }
4126  }
4127 
4128  // determine all new paragraphs
4129  foreach ($r_hashes as $pc_id => $h)
4130  {
4131  if (!isset($l_hashes[$pc_id]))
4132  {
4133  $r_hashes[$pc_id]["change"] = "New";
4134  }
4135  }
4136 
4137  $l_page->addChangeDivClasses($l_hashes);
4138  $r_page->addChangeDivClasses($r_hashes);
4139 
4140  return array("l_page" => $l_page, "r_page" => $r_page,
4141  "l_changes" => $l_hashes, "r_changes" => $r_hashes);
4142  }
4143 
4147  function increaseViewCnt()
4148  {
4149  global $ilDB;
4150 
4151  $ilDB->manipulate("UPDATE page_object ".
4152  " SET view_cnt = view_cnt + 1 ".
4153  " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
4154  " AND parent_type = ".$ilDB->quote($this->getParentType(), "text"));
4155  //$ilDB->query($q);
4156  }
4157 
4165  static function getRecentChanges($a_parent_type, $a_parent_id, $a_period = 30)
4166  {
4167  global $ilDB;
4168 
4169  $page_changes = array();
4170  $limit_ts = date('Y-m-d H:i:s', time() - ($a_period * 24 * 60 * 60));
4171  $q = "SELECT * FROM page_object ".
4172  " WHERE parent_id = ".$ilDB->quote($a_parent_id, "integer").
4173  " AND parent_type = ".$ilDB->quote($a_parent_type, "text").
4174  " AND last_change >= ".$ilDB->quote($limit_ts, "timestamp");
4175  // " AND (TO_DAYS(now()) - TO_DAYS(last_change)) <= ".((int)$a_period);
4176  $set = $ilDB->query($q);
4177  while($page = $ilDB->fetchAssoc($set))
4178  {
4179  $page_changes[] = array("date" => $page["last_change"],
4180  "id" => $page["page_id"], "type" => "page",
4181  "user" => $page["last_change_user"]);
4182  }
4183 
4184  $and_str = "";
4185  if ($a_period > 0)
4186  {
4187  $limit_ts = date('Y-m-d H:i:s', time() - ($a_period * 24 * 60 * 60));
4188  $and_str = " AND hdate >= ".$ilDB->quote($limit_ts, "timestamp")." ";
4189  }
4190 
4191  $q = "SELECT * FROM page_history ".
4192  " WHERE parent_id = ".$ilDB->quote($a_parent_id, "integer").
4193  " AND parent_type = ".$ilDB->quote($a_parent_type, "text").
4194  $and_str;
4195  $set = $ilDB->query($q);
4196  while ($page = $ilDB->fetchAssoc($set))
4197  {
4198  $page_changes[] = array("date" => $page["hdate"],
4199  "id" => $page["page_id"], "type" => "hist", "nr" => $page["nr"],
4200  "user" => $page["user_id"]);
4201  }
4202 
4203  $page_changes = ilUtil::sortArray($page_changes, "date", "desc");
4204 
4205  return $page_changes;
4206  }
4207 
4215  static function getAllPages($a_parent_type, $a_parent_id)
4216  {
4217  global $ilDB;
4218 
4219  $page_changes = array();
4220 
4221  $q = "SELECT * FROM page_object ".
4222  " WHERE parent_id = ".$ilDB->quote($a_parent_id, "integer").
4223  " AND parent_type = ".$ilDB->quote($a_parent_type, "text");
4224  $set = $ilDB->query($q);
4225  $pages = array();
4226  while ($page = $ilDB->fetchAssoc($set))
4227  {
4228  $pages[$page["page_id"]] = array("date" => $page["last_change"],
4229  "id" => $page["page_id"], "user" => $page["last_change_user"]);
4230  }
4231 
4232  return $pages;
4233  }
4234 
4241  static function getNewPages($a_parent_type, $a_parent_id)
4242  {
4243  global $ilDB;
4244 
4245  $pages = array();
4246 
4247  $q = "SELECT * FROM page_object ".
4248  " WHERE parent_id = ".$ilDB->quote($a_parent_id, "integer").
4249  " AND parent_type = ".$ilDB->quote($a_parent_type, "text").
4250  " ORDER BY created DESC";
4251  $set = $ilDB->query($q);
4252  while($page = $ilDB->fetchAssoc($set))
4253  {
4254  if ($page["created"] != "")
4255  {
4256  $pages[] = array("created" => $page["created"],
4257  "id" => $page["page_id"],
4258  "user" => $page["create_user"],
4259  );
4260  }
4261  }
4262 
4263  return $pages;
4264  }
4265 
4272  static function getParentObjectContributors($a_parent_type, $a_parent_id)
4273  {
4274  global $ilDB;
4275 
4276  $contributors = array();
4277  $set = $ilDB->queryF("SELECT last_change_user FROM page_object ".
4278  " WHERE parent_id = %s AND parent_type = %s ".
4279  " AND last_change_user != %s",
4280  array("integer", "text", "integer"),
4281  array($a_parent_id, $a_parent_type, 0));
4282 
4283  while ($page = $ilDB->fetchAssoc($set))
4284  {
4285  $contributors[$page["last_change_user"]][$page["page_id"]] = 1;
4286  }
4287 
4288  $set = $ilDB->queryF("SELECT count(*) as cnt, page_id, user_id FROM page_history ".
4289  " WHERE parent_id = %s AND parent_type = %s AND user_id != %s ".
4290  " GROUP BY page_id, user_id ",
4291  array("integer", "text", "integer"),
4292  array($a_parent_id, $a_parent_type, 0));
4293  while ($hpage = $ilDB->fetchAssoc($set))
4294  {
4295  $contributors[$hpage["user_id"]][$hpage["page_id"]] =
4296  $contributors[$hpage["user_id"]][$hpage["page_id"]] + $hpage["cnt"];
4297  }
4298 
4299  $c = array();
4300  foreach ($contributors as $k => $co)
4301  {
4302  $name = ilObjUser::_lookupName($k);
4303  $c[] = array("user_id" => $k, "pages" => $co,
4304  "lastname" => $name["lastname"], "firstname" => $name["firstname"]);
4305  }
4306 
4307  return $c;
4308  }
4309 
4316  static function getPageContributors($a_parent_type, $a_page_id)
4317  {
4318  global $ilDB;
4319 
4320  $contributors = array();
4321  $set = $ilDB->queryF("SELECT last_change_user FROM page_object ".
4322  " WHERE page_id = %s AND parent_type = %s ".
4323  " AND last_change_user != %s",
4324  array("integer", "text", "integer"),
4325  array($a_page_id, $a_parent_type, 0));
4326 
4327  while ($page = $ilDB->fetchAssoc($set))
4328  {
4329  $contributors[$page["last_change_user"]] = 1;
4330  }
4331 
4332  $set = $ilDB->queryF("SELECT count(*) as cnt, page_id, user_id FROM page_history ".
4333  " WHERE page_id = %s AND parent_type = %s AND user_id != %s ".
4334  " GROUP BY user_id, page_id ",
4335  array("integer", "text", "integer"),
4336  array($a_page_id, $a_parent_type, 0));
4337  while ($hpage = $ilDB->fetchAssoc($set))
4338  {
4339  $contributors[$hpage["user_id"]] =
4340  $contributors[$hpage["user_id"]] + $hpage["cnt"];
4341  }
4342 
4343  $c = array();
4344  foreach ($contributors as $k => $co)
4345  {
4346  $name = ilObjUser::_lookupName($k);
4347  $c[] = array("user_id" => $k, "pages" => $co,
4348  "lastname" => $name["lastname"], "firstname" => $name["firstname"]);
4349  }
4350 
4351  return $c;
4352  }
4353 
4357  function writeRenderedContent($a_content, $a_md5)
4358  {
4359  global $ilDB;
4360 
4361  $ilDB->update("page_object", array(
4362  "rendered_content" => array("clob", $a_content),
4363  "render_md5" => array("text", $a_md5),
4364  "rendered_time" => array("timestamp", ilUtil::now())
4365  ), array(
4366  "page_id" => array("integer", $this->getId()),
4367  "parent_type" => array("text", $this->getParentType())
4368  ));
4369  /*$st = $ilDB->prepareManip("UPDATE page_object ".
4370  " SET rendered_content = ?, render_md5 = ?, rendered_time = now()".
4371  " WHERE page_id = ? AND parent_type = ?",
4372  array("text", "text", "integer", "text"));
4373  $r = $ilDB->execute($st,
4374  array($a_content, $a_md5, $this->getId(), $this->getParentType()));*/
4375  }
4376 
4384  static function getPagesWithLinks($a_parent_type, $a_parent_id)
4385  {
4386  global $ilDB;
4387 
4388  $page_changes = array();
4389 
4390  $q = "SELECT * FROM page_object ".
4391  " WHERE parent_id = ".$ilDB->quote($a_parent_id, "integer").
4392  " AND parent_type = ".$ilDB->quote($a_parent_type, "text").
4393  " AND int_links = ".$ilDB->quote(1, "integer");
4394  $set = $ilDB->query($q);
4395  $pages = array();
4396  while ($page = $ilDB->fetchAssoc($set))
4397  {
4398  $pages[$page["page_id"]] = array("date" => $page["last_change"],
4399  "id" => $page["page_id"], "user" => $page["last_change_user"]);
4400  }
4401 
4402  return $pages;
4403  }
4404 
4411  function containsIntLinks($a_content)
4412  {
4413  if (strpos($a_content, "IntLink"))
4414  {
4415  return true;
4416  }
4417  return false;
4418  }
4419 
4424  {
4425  }
4426 }
4427 ?>