ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
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
4define("IL_INSERT_BEFORE", 0);
5define("IL_INSERT_AFTER", 1);
6define("IL_INSERT_CHILD", 2);
7
8define ("IL_CHAPTER_TITLE", "st_title");
9define ("IL_PAGE_TITLE", "pg_title");
10define ("IL_NO_HEADER", "none");
11
15/*
16 @todo 1
17
18 - All PC types could be defined in service/module xml. (done)
19 -- type, class, directory (done)
20 -- internal links used/implemented?
21 -- styles used/implemented?
22 - application classes need
23 -- page object
24 --- page object should return php5 domdoc (getDom() vs getDomDoc()?)
25 esp. plugins should use this
26 -- remove content element hook, if content is not allowed
27 - PC types could move to components (e.g. blog, login)
28 - Problem: How to modularize xsl?
29 -- read from db?
30 -- xml entries say that xslt code is used -> read file and include in
31 main xslt file
32
33*/
34
46abstract class ilPageObject
47{
48 static $exists = array();
49
50 var $id;
51 var $ilias;
52 var $dom;
53 var $xml;
55 var $node;
56 var $cur_dtd = "ilias_pg_5_2.dtd";
66 var $language = "-";
67 static protected $activation_data = array();
68 protected $import_mode = false;
69
73 protected $log;
74
79 final public function __construct($a_id = 0, $a_old_nr = 0, $a_lang = "-")
80 {
81 global $ilias;
82
83 $this->log = ilLoggerFactory::getLogger('copg');
84
85 // @todo: move this elsewhere
86// require_once("./Services/COPage/syntax_highlight/php/Beautifier/Init.php");
87// require_once("./Services/COPage/syntax_highlight/php/Output/Output_css.php");
88
89 $this->parent_type = $this->getParentType();
90 $this->id = $a_id;
91 $this->ilias = $ilias;
92 $this->setLanguage($a_lang);
93
94 $this->contains_int_link = false;
95 $this->needs_parsing = false;
96 $this->update_listeners = array();
97 $this->update_listener_cnt = 0;
98 $this->dom_builded = false;
99 $this->page_not_found = false;
100 $this->old_nr = $a_old_nr;
101 $this->encoding = "UTF-8";
102 $this->id_elements =
103 array("PageContent", "TableRow", "TableData", "ListItem", "FileItem",
104 "Section", "Tab", "ContentPopup");
105 $this->setActive(true);
106 $this->show_page_act_info = false;
107
108 if($a_id != 0)
109 {
110 $this->read();
111 }
112
113 $this->initPageConfig();
114
115 $this->afterConstructor();
116 }
117
125 {
126
127 }
128
129
135 abstract function getParentType();
136
142 final function initPageConfig()
143 {
144 include_once("./Services/COPage/classes/class.ilPageObjectFactory.php");
146 $this->setPageConfig($cfg);
147 }
148
154 function setLanguage($a_val)
155 {
156 $this->language = $a_val;
157 }
158
164 function getLanguage()
165 {
166 return $this->language;
167 }
168
174 function setPageConfig($a_val)
175 {
176 $this->page_config = $a_val;
177 }
178
184 function getPageConfig()
185 {
186 return $this->page_config;
187 }
188
194 function setRenderMd5($a_rendermd5)
195 {
196 $this->rendermd5 = $a_rendermd5;
197 }
198
204 function getRenderMd5()
205 {
206 return $this->rendermd5;
207 }
208
214 function setRenderedContent($a_renderedcontent)
215 {
216 $this->renderedcontent = $a_renderedcontent;
217 }
218
225 {
226 return $this->renderedcontent;
227 }
228
234 function setRenderedTime($a_renderedtime)
235 {
236 $this->renderedtime = $a_renderedtime;
237 }
238
245 {
246 return $this->renderedtime;
247 }
248
254 function setLastChange($a_lastchange)
255 {
256 $this->lastchange = $a_lastchange;
257 }
258
264 function getLastChange()
265 {
266 return $this->lastchange;
267 }
268
274 public function setLastChangeUser($a_val)
275 {
276 $this->last_change_user = $a_val;
277 }
278
284 public function getLastChangeUser()
285 {
286 return $this->last_change_user;
287 }
288
294 function setShowActivationInfo($a_val)
295 {
296 $this->show_page_act_info = $a_val;
297 }
298
305 {
306 return $this->show_page_act_info;
307 }
308
312 function read()
313 {
314 global $ilDB;
315
316 $this->setActive(true);
317 if ($this->old_nr == 0)
318 {
319 $query = "SELECT * FROM page_object".
320 " WHERE page_id = ".$ilDB->quote($this->id, "integer").
321 " AND parent_type=".$ilDB->quote($this->getParentType(), "text").
322 " AND lang = ".$ilDB->quote($this->getLanguage(), "text");
323 $pg_set = $this->ilias->db->query($query);
324 $this->page_record = $ilDB->fetchAssoc($pg_set);
325 $this->setActive($this->page_record["active"]);
326 $this->setActivationStart($this->page_record["activation_start"]);
327 $this->setActivationEnd($this->page_record["activation_end"]);
328 $this->setShowActivationInfo($this->page_record["show_activation_info"]);
329 }
330 else
331 {
332 $query = "SELECT * FROM page_history".
333 " WHERE page_id = ".$ilDB->quote($this->id, "integer").
334 " AND parent_type=".$ilDB->quote($this->getParentType(), "text").
335 " AND nr = ".$ilDB->quote((int) $this->old_nr, "integer").
336 " AND lang = ".$ilDB->quote($this->getLanguage(), "text");
337 $pg_set = $ilDB->query($query);
338 $this->page_record = $ilDB->fetchAssoc($pg_set);
339 }
340 if (!$this->page_record)
341 {
342 include_once("./Services/COPage/exceptions/class.ilCOPageNotFoundException.php");
343 throw new ilCOPageNotFoundException("Error: Page ".$this->id." is not in database".
344 " (parent type ".$this->getParentType().", lang: ".$this->getLanguage().").");
345 }
346
347 $this->xml = $this->page_record["content"];
348 $this->setParentId($this->page_record["parent_id"]);
349 $this->last_change_user = $this->page_record["last_change_user"];
350 $this->create_user = $this->page_record["create_user"];
351 $this->setRenderedContent($this->page_record["rendered_content"]);
352 $this->setRenderMd5($this->page_record["render_md5"]);
353 $this->setRenderedTime($this->page_record["rendered_time"]);
354 $this->setLastChange($this->page_record["last_change"]);
355
356 }
357
365 static function _exists($a_parent_type, $a_id, $a_lang = "", $a_no_cache = false)
366 {
367 global $ilDB;
368 if (!$a_no_cache && isset(self::$exists[$a_parent_type.":".$a_id.":".$a_lang]))
369 {
370 return self::$exists[$a_parent_type.":".$a_id.":".$a_lang];
371 }
372
373 $and_lang = "";
374 if ($a_lang != "")
375 {
376 $and_lang = " AND lang = ".$ilDB->quote($a_lang, "text");
377 }
378
379 $query = "SELECT page_id FROM page_object WHERE page_id = ".$ilDB->quote($a_id, "integer")." ".
380 "AND parent_type = ".$ilDB->quote($a_parent_type, "text").$and_lang;
381 $set = $ilDB->query($query);
382 if ($row = $ilDB->fetchAssoc($set))
383 {
384 self::$exists[$a_parent_type.":".$a_id.":".$a_lang] = true;
385 return true;
386 }
387 else
388 {
389 self::$exists[$a_parent_type.":".$a_id.":".$a_lang] = false;
390 return false;
391 }
392 }
393
401 static function _existsAndNotEmpty($a_parent_type, $a_id, $a_lang = "-")
402 {
403 global $ilDB;
404
405 include_once("./Services/COPage/classes/class.ilPageUtil.php");
406
407 return ilPageUtil::_existsAndNotEmpty($a_parent_type, $a_id, $a_lang);
408 }
409
410 function buildDom($a_force = false)
411 {
412 if ($this->dom_builded && !$a_force)
413 {
414 return;
415 }
416
417//echo "\n<br>buildDomWith:".$this->getId().":xml:".$this->getXMLContent(true).":<br>";
418
419 $options = 0;
420 //$options = DOMXML_LOAD_VALIDATING;
421 //$options = LIBXML_DTDLOAD;
422 //$options = LIBXML_NOXMLDECL;
423//echo htmlentities($this->getXMLContent(true))."<br>";
424 $this->dom = @domxml_open_mem($this->getXMLContent(true), $options, $error);
425//var_dump($error);
426 $xpc = xpath_new_context($this->dom);
427 $path = "//PageObject";
428 $res = xpath_eval($xpc, $path);
429 if (count($res->nodeset) == 1)
430 {
431// echo "h";
432 $this->node = $res->nodeset[0];
433 }
434//echo htmlentities($this->dom->dump_node($this->node)); exit;
435
436 if (empty($error))
437 {
438 $this->dom_builded = true;
439 return true;
440 }
441 else
442 {
443 return $error;
444 }
445 }
446
447 function freeDom()
448 {
449 //$this->dom->free();
450 unset($this->dom);
451 }
452
456 function getDom()
457 {
458 return $this->dom;
459 }
460
467 function getDomDoc()
468 {
469 if ($this->dom instanceof php4DOMDocument)
470 {
471 return $this->dom->myDOMDocument;
472 }
473
474 return $this->dom;
475 }
476
477
481 function setId($a_id)
482 {
483 $this->id = $a_id;
484 }
485
486 function getId()
487 {
488 return $this->id;
489 }
490
491 function setParentId($a_id)
492 {
493 $this->parent_id = $a_id;
494 }
495
496 function getParentId()
497 {
498 return $this->parent_id;
499 }
500
501 function addUpdateListener(&$a_object, $a_method, $a_parameters = "")
502 {
504 $this->update_listeners[$cnt]["object"] = $a_object;
505 $this->update_listeners[$cnt]["method"] = $a_method;
506 $this->update_listeners[$cnt]["parameters"] = $a_parameters;
507 $this->update_listener_cnt++;
508 }
509
511 {
512 for($i=0; $i<$this->update_listener_cnt; $i++)
513 {
514 $object = $this->update_listeners[$i]["object"];
515 $method = $this->update_listeners[$i]["method"];
516 $parameters = $this->update_listeners[$i]["parameters"];
517 $object->$method($parameters);
518 }
519 }
520
526 function setActive($a_active)
527 {
528 $this->active = $a_active;
529 }
530
536 function getActive($a_check_scheduled_activation = false)
537 {
538 if ($a_check_scheduled_activation && !$this->active)
539 {
540 include_once("./Services/Calendar/classes/class.ilDateTime.php");
542 $end = new ilDateTime($this->getActivationEnd(), IL_CAL_DATETIME);
543 $now = new ilDateTime(time(), IL_CAL_UNIX);
544 if (!ilDateTime::_before($now, $start) && !ilDateTime::_after($now, $end))
545 {
546 return true;
547 }
548 }
549 return $this->active;
550 }
551
557 static function preloadActivationDataByParentId($a_parent_id)
558 {
559 global $ilDB;
560
561 $set = $ilDB->query("SELECT page_id, parent_type, lang, active, activation_start, activation_end, show_activation_info FROM page_object ".
562 " WHERE parent_id = ".$ilDB->quote($a_parent_id, "integer")
563 );
564 while ($rec = $ilDB->fetchAssoc($set))
565 {
566 self::$activation_data[$rec["page_id"].":".$rec["parent_type"].":".$rec["lang"]] = $rec;
567 }
568 }
569
570
574 static function _lookupActive($a_id, $a_parent_type, $a_check_scheduled_activation = false, $a_lang = "-")
575 {
576 global $ilDB;
577
578 // language must be set at least to "-"
579 if ($a_lang == "")
580 {
581 $a_lang = "-";
582 }
583
584 if (isset(self::$activation_data[$a_id.":".$a_parent_type.":".$a_lang]))
585 {
586 $rec = self::$activation_data[$a_id.":".$a_parent_type.":".$a_lang];
587 }
588 else
589 {
590 $set = $ilDB->queryF("SELECT active, activation_start, activation_end FROM page_object WHERE page_id = %s".
591 " AND parent_type = %s AND lang = %s",
592 array("integer", "text", "text"),
593 array($a_id, $a_parent_type, $a_lang));
594 $rec = $ilDB->fetchAssoc($set);
595 }
596
597
598 $rec["n"] = ilUtil::now();
599
600 if (!$rec["active"] && $a_check_scheduled_activation)
601 {
602 if ($rec["n"] >= $rec["activation_start"] &&
603 $rec["n"] <= $rec["activation_end"])
604 {
605 return true;
606 }
607 }
608
609 return $rec["active"];
610 }
611
615 static function _isScheduledActivation($a_id, $a_parent_type, $a_lang = "-")
616 {
617 global $ilDB;
618
619 // language must be set at least to "-"
620 if ($a_lang == "")
621 {
622 $a_lang = "-";
623 }
624
625//echo "<br>";
626//var_dump(self::$activation_data); exit;
627 if (isset(self::$activation_data[$a_id.":".$a_parent_type.":".$a_lang]))
628 {
629 $rec = self::$activation_data[$a_id.":".$a_parent_type.":".$a_lang];
630 }
631 else
632 {
633 $set = $ilDB->queryF("SELECT active, activation_start, activation_end FROM page_object WHERE page_id = %s".
634 " AND parent_type = %s AND lang = %s", array("integer", "text", "text"),
635 array($a_id, $a_parent_type, $a_lang));
636 $rec = $ilDB->fetchAssoc($set);
637 }
638
639 if (!$rec["active"] && $rec["activation_start"] != "")
640 {
641 return true;
642 }
643
644 return false;
645 }
646
650 static function _writeActive($a_id, $a_parent_type, $a_active, $a_reset_scheduled_activation = true, $a_lang = "-")
651 {
652 global $ilDB;
653
654 // language must be set at least to "-"
655 if ($a_lang == "")
656 {
657 $a_lang = "-";
658 }
659
660 if ($a_reset_scheduled_activation)
661 {
662 $st = $ilDB->manipulateF("UPDATE page_object SET active = %s, activation_start = %s, ".
663 " activation_end = %s WHERE page_id = %s".
664 " AND parent_type = %s AND lang = %s", array("boolean", "timestamp", "timestamp", "integer", "text", "text"),
665 array($a_active, null, null, $a_id, $a_parent_type, $a_lang));
666 }
667 else
668 {
669 $st = $ilDB->prepareManip("UPDATE page_object SET active = %s WHERE page_id = %s".
670 " AND parent_type = %s AND lang = %s", array("boolean", "integer", "text", "text"),
671 array($a_active, $a_id, $a_parent_type, $a_lang));
672 }
673 }
674
678 static function _lookupActivationData($a_id, $a_parent_type, $a_lang = "-")
679 {
680 global $ilDB;
681
682 // language must be set at least to "-"
683 if ($a_lang == "")
684 {
685 $a_lang = "-";
686 }
687
688 if (isset(self::$activation_data[$a_id.":".$a_parent_type.":".$a_lang]))
689 {
690 $rec = self::$activation_data[$a_id.":".$a_parent_type.":".$a_lang];
691 }
692 else
693 {
694 $set = $ilDB->queryF("SELECT active, activation_start, activation_end, show_activation_info FROM page_object WHERE page_id = %s".
695 " AND parent_type = %s AND lang = %s",
696 array("integer", "text", "text"),
697 array($a_id, $a_parent_type, $a_lang));
698 $rec = $ilDB->fetchAssoc($set);
699 }
700
701 return $rec;
702 }
703
704
708 static function lookupParentId($a_id, $a_type)
709 {
710 global $ilDB;
711
712 $res = $ilDB->query("SELECT parent_id FROM page_object WHERE page_id = ".$ilDB->quote($a_id, "integer")." ".
713 "AND parent_type=".$ilDB->quote($a_type, "text"));
714 $rec = $ilDB->fetchAssoc($res);
715 return $rec["parent_id"];
716 }
717
721 static function _writeParentId($a_parent_type, $a_pg_id, $a_par_id)
722 {
723 global $ilDB;
724
725 $st = $ilDB->manipulateF("UPDATE page_object SET parent_id = %s WHERE page_id = %s".
726 " AND parent_type = %s", array("integer", "integer", "text"),
727 array($a_par_id, $a_pg_id, $a_parent_type));
728 }
729
735 function setActivationStart($a_activationstart)
736 {
737 if ($a_activationstart == "")
738 {
739 $a_activationstart = null;
740 }
741 $this->activationstart = $a_activationstart;
742 }
743
750 {
751 return $this->activationstart;
752 }
753
759 function setActivationEnd($a_activationend)
760 {
761 if ($a_activationend == "")
762 {
763 $a_activationend = null;
764 }
765 $this->activationend = $a_activationend;
766 }
767
774 {
775 return $this->activationend;
776 }
777
786 function getContentObject($a_hier_id, $a_pc_id = "")
787 {
788 $cont_node = $this->getContentNode($a_hier_id, $a_pc_id);
789 if (!is_object($cont_node))
790 {
791 return false;
792 }
793 include_once("./Services/COPage/classes/class.ilCOPagePCDef.php");
794 $node_name = $cont_node->node_name();
795 if ($node_name == "PageObject")
796 {
797 return null;
798 }
799 if ($node_name == "PageContent")
800 {
801 $child_node = $cont_node->first_child();
802 $node_name = $child_node->node_name();
803 }
804
805 // table extra handling (@todo: get rid of it)
806 if ($node_name == "Table")
807 {
808 if ($child_node->get_attribute("DataTable") == "y")
809 {
810 require_once("./Services/COPage/classes/class.ilPCDataTable.php");
811 $tab = new ilPCDataTable($this);
812 $tab->setNode($cont_node);
813 $tab->setHierId($a_hier_id);
814 }
815 else
816 {
817 require_once("./Services/COPage/classes/class.ilPCTable.php");
818 $tab = new ilPCTable($this);
819 $tab->setNode($cont_node);
820 $tab->setHierId($a_hier_id);
821 }
822 $tab->setPcId($a_pc_id);
823 return $tab;
824 }
825
826 // media extra handling (@todo: get rid of it)
827 if ($node_name == "MediaObject")
828 {
829 if ($_GET["pgEdMediaMode"] != "") {echo "ilPageObject::error media"; exit;}
830
831 //require_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
832 require_once("./Services/COPage/classes/class.ilPCMediaObject.php");
833
834 $mal_node = $child_node->first_child();
835//echo "ilPageObject::getContentObject:nodename:".$mal_node->node_name().":<br>";
836 $id_arr = explode("_", $mal_node->get_attribute("OriginId"));
837 $mob_id = $id_arr[count($id_arr) - 1];
838
839 // allow deletion of non-existing media objects
840 if (!ilObject::_exists($mob_id) && in_array("delete", $_POST))
841 {
842 $mob_id = 0;
843 }
844
845 //$mob = new ilObjMediaObject($mob_id);
846 $mob = new ilPCMediaObject($this);
847 $mob->readMediaObject($mob_id);
848
849 //$mob->setDom($this->dom);
850 $mob->setNode($cont_node);
851 $mob->setHierId($a_hier_id);
852 $mob->setPcId($a_pc_id);
853 return $mob;
854 }
855
856 //
857 // generic procedure
858 //
859
860 $pc_def = ilCOPagePCDef::getPCDefinitionByName($node_name);
861
862 // check if pc definition has been found
863 if (!is_array($pc_def))
864 {
865 include_once("./Services/COPage/exceptions/class.ilCOPageUnknownPCTypeException.php");
866 throw new ilCOPageUnknownPCTypeException('Unknown PC Name "'.$node_name.'".');
867 }
868 $pc_class = "ilPC".$pc_def["name"];
869 $pc_path = "./".$pc_def["component"]."/".$pc_def["directory"]."/class.".$pc_class.".php";
870 require_once($pc_path);
871 $pc = new $pc_class($this);
872 $pc->setNode($cont_node);
873 $pc->setHierId($a_hier_id);
874 $pc->setPcId($a_pc_id);
875 return $pc;
876 }
877
884 function &getContentNode($a_hier_id, $a_pc_id = "")
885 {
886 $xpc = xpath_new_context($this->dom);
887 if($a_hier_id == "pg")
888 {
889 return $this->node;
890 }
891 else
892 {
893 // get per pc id
894 if ($a_pc_id != "")
895 {
896 $path = "//*[@PCID = '$a_pc_id']";
897 $res = xpath_eval($xpc, $path);
898 if (count($res->nodeset) == 1)
899 {
900 $cont_node = $res->nodeset[0];
901 return $cont_node;
902 }
903 }
904
905 // fall back to hier id
906 $path = "//*[@HierId = '$a_hier_id']";
907 $res = xpath_eval($xpc, $path);
908 if (count($res->nodeset) == 1)
909 {
910 $cont_node = $res->nodeset[0];
911 return $cont_node;
912 }
913 }
914 }
915
922 function checkForTag($a_content_tag, $a_hier_id, $a_pc_id = "")
923 {
924 $xpc = xpath_new_context($this->dom);
925 // get per pc id
926 if ($a_pc_id != "")
927 {
928 $path = "//*[@PCID = '$a_pc_id']//".$a_content_tag;
929 $res = xpath_eval($xpc, $path);
930 if (count($res->nodeset) > 0)
931 {
932 return true;
933 }
934 }
935
936 // fall back to hier id
937 $path = "//*[@HierId = '$a_hier_id']//".$a_content_tag;
938 $res = xpath_eval($xpc, $path);
939 if (count($res->nodeset) > 0)
940 {
941 return true;
942 }
943 return false;
944 }
945
946 // only for test purposes
947 function lookforhier($a_hier_id)
948 {
949 $xpc = xpath_new_context($this->dom);
950 $path = "//*[@HierId = '$a_hier_id']";
951 $res = xpath_eval($xpc, $path);
952 if (count($res->nodeset) == 1)
953 return "YES";
954 else
955 return "NO";
956 }
957
958
959 function &getNode()
960 {
961 return $this->node;
962 }
963
964
973 function setXMLContent($a_xml, $a_encoding = "UTF-8")
974 {
975 $this->encoding = $a_encoding;
976 $this->xml = $a_xml;
977 }
978
985 function appendXMLContent($a_xml)
986 {
987 $this->xml.= $a_xml;
988 }
989
990
994 function getXMLContent($a_incl_head = false)
995 {
996 // build full http path for XML DOCTYPE header.
997 // Under windows a relative path doesn't work :-(
998 if($a_incl_head)
999 {
1000//echo "+".$this->encoding."+";
1001 $enc_str = (!empty($this->encoding))
1002 ? "encoding=\"".$this->encoding."\""
1003 : "";
1004 return "<?xml version=\"1.0\" $enc_str ?>".
1005 "<!DOCTYPE PageObject SYSTEM \"".ILIAS_ABSOLUTE_PATH."/xml/".$this->cur_dtd."\">".
1006 $this->xml;
1007 }
1008 else
1009 {
1010 return $this->xml;
1011 }
1012 }
1013
1018 function copyXmlContent($a_clone_mobs = false)
1019 {
1020 $xml = $this->getXmlContent();
1021 $temp_dom = domxml_open_mem('<?xml version="1.0" encoding="UTF-8"?>'.$xml,
1022 DOMXML_LOAD_PARSING, $error);
1023 if(empty($error))
1024 {
1025 $this->handleCopiedContent($temp_dom, true, $a_clone_mobs);
1026 }
1027 $xml = $temp_dom->dump_mem(0, $this->encoding);
1028 $xml = preg_replace('/<\?xml[^>]*>/i',"",$xml);
1029 $xml = preg_replace('/<!DOCTYPE[^>]*>/i',"",$xml);
1030
1031 return $xml;
1032 }
1033
1034// @todo 1: begin: generalize, remove concrete dependencies
1035
1045 function handleCopiedContent($a_dom, $a_self_ass = true, $a_clone_mobs = false)
1046 {
1047 include_once("./Services/COPage/classes/class.ilCOPagePCDef.php");
1049
1050 // handle question elements
1051 if ($a_self_ass)
1052 {
1053 $this->newQuestionCopies($a_dom);
1054 }
1055 else
1056 {
1057 $this->removeQuestions($a_dom);
1058 }
1059
1060 // handle interactive images
1061 $this->newIIMCopies($a_dom);
1062
1063 // handle media objects
1064 if ($a_clone_mobs)
1065 {
1066 $this->newMobCopies($a_dom);
1067 }
1068
1069// @todo 1: move all functions from above to the new domdoc
1070 if ($a_dom instanceof php4DOMDocument)
1071 {
1072 $a_dom = $a_dom->myDOMDocument;
1073 }
1074 foreach ($defs as $def)
1075 {
1077 $cl = $def["pc_class"];
1078 $cl::handleCopiedContent($a_dom, $a_self_ass, $a_clone_mobs);
1079 }
1080
1081 }
1082
1087 function newIIMCopies($temp_dom)
1088 {
1089 // Get question IDs
1090 $path = "//InteractiveImage/MediaAlias";
1091 $xpc = xpath_new_context($temp_dom);
1092 $res = & xpath_eval($xpc, $path);
1093
1094 $q_ids = array();
1095 include_once("./Services/Link/classes/class.ilInternalLink.php");
1096 for ($i = 0; $i < count ($res->nodeset); $i++)
1097 {
1098 $or_id = $res->nodeset[$i]->get_attribute("OriginId");
1099
1100 $inst_id = ilInternalLink::_extractInstOfTarget($or_id);
1101 $mob_id = ilInternalLink::_extractObjIdOfTarget($or_id);
1102
1103 if (!($inst_id > 0))
1104 {
1105 if ($mob_id > 0)
1106 {
1107 include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
1108 $media_object = new ilObjMediaObject($mob_id);
1109
1110 // now copy this question and change reference to
1111 // new question id
1112 $new_mob = $media_object->duplicate();
1113
1114 $res->nodeset[$i]->set_attribute("OriginId", "il__mob_".$new_mob->getId());
1115 }
1116 }
1117 }
1118 }
1119
1123 function newMobCopies($temp_dom)
1124 {
1125 // Get question IDs
1126 $path = "//MediaObject/MediaAlias";
1127 $xpc = xpath_new_context($temp_dom);
1128 $res = & xpath_eval($xpc, $path);
1129
1130 $q_ids = array();
1131 include_once("./Services/Link/classes/class.ilInternalLink.php");
1132 for ($i = 0; $i < count ($res->nodeset); $i++)
1133 {
1134 $or_id = $res->nodeset[$i]->get_attribute("OriginId");
1135
1136 $inst_id = ilInternalLink::_extractInstOfTarget($or_id);
1137 $mob_id = ilInternalLink::_extractObjIdOfTarget($or_id);
1138
1139 if (!($inst_id > 0))
1140 {
1141 if ($mob_id > 0)
1142 {
1143 include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
1144 $media_object = new ilObjMediaObject($mob_id);
1145
1146 // now copy this question and change reference to
1147 // new question id
1148 $new_mob = $media_object->duplicate();
1149
1150 $res->nodeset[$i]->set_attribute("OriginId", "il__mob_".$new_mob->getId());
1151 }
1152 }
1153 }
1154 }
1155
1160 function newQuestionCopies(&$temp_dom)
1161 {
1162 // Get question IDs
1163 $path = "//Question";
1164 $xpc = xpath_new_context($temp_dom);
1165 $res = & xpath_eval($xpc, $path);
1166
1167 $q_ids = array();
1168 include_once("./Services/Link/classes/class.ilInternalLink.php");
1169 for ($i = 0; $i < count ($res->nodeset); $i++)
1170 {
1171 $qref = $res->nodeset[$i]->get_attribute("QRef");
1172
1173 $inst_id = ilInternalLink::_extractInstOfTarget($qref);
1175
1176 if (!($inst_id > 0))
1177 {
1178 if ($q_id > 0)
1179 {
1180 include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
1181 $question = assQuestion::_instantiateQuestion($q_id);
1182 // check due to #16557
1183 if (is_object($question) && $question->isComplete())
1184 {
1185 // check if page for question exists
1186 // due to a bug in early 4.2.x version this is possible
1187 if (!ilPageObject::_exists("qpl", $q_id))
1188 {
1189 $question->createPageObject();
1190 }
1191
1192 // now copy this question and change reference to
1193 // new question id
1194 $duplicate_id = $question->duplicate(false);
1195 $res->nodeset[$i]->set_attribute("QRef", "il__qst_".$duplicate_id);
1196 }
1197 }
1198 }
1199 }
1200 }
1201
1208 function removeQuestions(&$temp_dom)
1209 {
1210 // Get question IDs
1211 $path = "//Question";
1212 $xpc = xpath_new_context($temp_dom);
1213 $res = & xpath_eval($xpc, $path);
1214 for ($i = 0; $i < count ($res->nodeset); $i++)
1215 {
1216 $parent_node = $res->nodeset[$i]->parent_node();
1217 $parent_node->unlink_node($parent_node);
1218 }
1219 }
1220
1221// @todo: end
1222
1230 {
1231 // Get question IDs
1232 $this->buildDom();
1233 $path = "//PageContent";
1234 $xpc = xpath_new_context($this->dom);
1235 $res = & xpath_eval($xpc, $path);
1236 return count ($res->nodeset);
1237 }
1238
1243 function getXMLFromDom($a_incl_head = false, $a_append_mobs = false, $a_append_bib = false,
1244 $a_append_str = "", $a_omit_pageobject_tag = false)
1245 {
1246 if ($a_incl_head)
1247 {
1248//echo "\n<br>#".$this->encoding."#";
1249 return $this->dom->dump_mem(0, $this->encoding);
1250 }
1251 else
1252 {
1253 // append multimedia object elements
1254 if ($a_append_mobs || $a_append_bib || $a_append_link_info)
1255 {
1256 $mobs = "";
1257 $bibs = "";
1258 if ($a_append_mobs)
1259 {
1260 $mobs = $this->getMultimediaXML();
1261 }
1262 if ($a_append_bib)
1263 {
1264// deprecated
1265// $bibs = $this->getBibliographyXML();
1266 }
1267 $trans = $this->getLanguageVariablesXML();
1268 //echo htmlentities($this->dom->dump_node($this->node)); exit;
1269 return "<dummy>".$this->dom->dump_node($this->node).$mobs.$bibs.$trans.$a_append_str."</dummy>";
1270 }
1271 else
1272 {
1273 if (is_object($this->dom))
1274 {
1275 if ($a_omit_pageobject_tag)
1276 {
1277 $xml = "";
1278 $childs = $this->node->child_nodes();
1279 for($i = 0; $i < count($childs); $i++)
1280 {
1281 $xml.= $this->dom->dump_node($childs[$i]);
1282 }
1283 return $xml;
1284 }
1285 else
1286 {
1287 $xml = $this->dom->dump_mem(0, $this->encoding);
1288 $xml = preg_replace('/<\?xml[^>]*>/i',"",$xml);
1289 $xml = preg_replace('/<!DOCTYPE[^>]*>/i',"",$xml);
1290 return $xml;
1291
1292 // don't use dump_node. This gives always entities.
1293 //return $this->dom->dump_node($this->node);
1294 }
1295 }
1296 else
1297 {
1298 return "";
1299 }
1300 }
1301 }
1302 }
1303
1308 {
1309 global $lng;
1310
1311 $xml = "<LVs>";
1312 $lang_vars = array(
1313 "ed_paste_clip", "ed_edit", "ed_edit_prop", "ed_delete", "ed_moveafter",
1314 "ed_movebefore", "ed_go", "ed_class", "ed_width", "ed_align_left",
1315 "ed_align_right", "ed_align_center", "ed_align_left_float",
1316 "ed_align_right_float", "ed_delete_item", "ed_new_item_before",
1317 "ed_new_item_after", "ed_copy_clip", "please_select", "ed_split_page",
1318 "ed_item_up", "ed_item_down", "ed_split_page_next","ed_enable",
1319 "de_activate", "ed_paste", "ed_edit_multiple", "ed_cut", "ed_copy", "ed_insert_templ",
1320 "ed_click_to_add_pg", "download");
1321
1322 // collect lang vars from pc elements
1323 include_once("./Services/COPage/classes/class.ilCOPagePCDef.php");
1325 foreach ($defs as $def)
1326 {
1327 $lang_vars[] = "pc_".$def["pc_type"];
1328 $lang_vars[] = "ed_insert_".$def["pc_type"];
1329
1331 $cl = $def["pc_class"];
1332 $lvs = call_user_func($def["pc_class"].'::getLangVars');
1333 foreach ($lvs as $lv)
1334 {
1335 $lang_vars[] = $lv;
1336 }
1337 }
1338
1339 foreach ($lang_vars as $lang_var)
1340 {
1341 $this->appendLangVarXML($xml, $lang_var);
1342 }
1343
1344 $xml.= "</LVs>";
1345
1346 return $xml;
1347 }
1348
1349 function appendLangVarXML(&$xml, $var)
1350 {
1351 global $lng;
1352
1353 $xml.= "<LV name=\"$var\" value=\"".$lng->txt("cont_".$var)."\"/>";
1354 }
1355
1356// @todo begin: move this to paragraph class
1357
1359 {
1360 if($this->dom)
1361 {
1362 require_once("./Services/COPage/classes/class.ilPCParagraph.php");
1363 $xpc = xpath_new_context($this->dom);
1364 $path = "//Paragraph[1]";
1365 $res = xpath_eval($xpc, $path);
1366 if (count($res->nodeset) > 0)
1367 {
1368 $cont_node = $res->nodeset[0]->parent_node();
1369 $par = new ilPCParagraph($this);
1370 $par->setNode($cont_node);
1371 return $par->getText();
1372 }
1373 }
1374 return "";
1375 }
1376
1383 function setParagraphContent($a_hier_id, $a_content)
1384 {
1385 $node = $this->getContentNode($a_hier_id);
1386 if (is_object($node))
1387 {
1388 $node->set_content($a_content);
1389 }
1390 }
1391
1392// @todo end
1393
1394
1403 // @todo: can we do this better
1404 function setContainsIntLink($a_contains_link)
1405 {
1406 $this->contains_int_link = $a_contains_link;
1407 }
1408
1413 // @todo: can we do this better
1415 {
1417 }
1418
1424 function setImportMode($a_val)
1425 {
1426 $this->import_mode = $a_val;
1427 }
1428
1434 function getImportMode()
1435 {
1436 return $this->import_mode;
1437 }
1438
1439 function needsImportParsing($a_parse = "")
1440 {
1441
1442 if ($a_parse === true)
1443 {
1444 $this->needs_parsing = true;
1445 }
1446 if ($a_parse === false)
1447 {
1448 $this->needs_parsing = false;
1449 }
1450 return $this->needs_parsing;
1451 }
1452
1458 // @todo: can we do this better
1459 public function setContainsQuestion($a_val)
1460 {
1461 $this->contains_question = $a_val;
1462 }
1463
1469 public function getContainsQuestion()
1470 {
1471 return $this->contains_question;
1472 }
1473
1474
1479 // @todo: move to media class
1480 function collectMediaObjects($a_inline_only = true)
1481 {
1482//echo htmlentities($this->getXMLFromDom());
1483 // determine all media aliases of the page
1484 $xpc = xpath_new_context($this->dom);
1485 $path = "//MediaObject/MediaAlias";
1486 $res = xpath_eval($xpc, $path);
1487 $mob_ids = array();
1488 for($i = 0; $i < count($res->nodeset); $i++)
1489 {
1490 $id_arr = explode("_", $res->nodeset[$i]->get_attribute("OriginId"));
1491 $mob_id = $id_arr[count($id_arr) - 1];
1492 $mob_ids[$mob_id] = $mob_id;
1493 }
1494
1495 // determine all media aliases of interactive images
1496 $xpc = xpath_new_context($this->dom);
1497 $path = "//InteractiveImage/MediaAlias";
1498 $res = xpath_eval($xpc, $path);
1499 for($i = 0; $i < count($res->nodeset); $i++)
1500 {
1501 $id_arr = explode("_", $res->nodeset[$i]->get_attribute("OriginId"));
1502 $mob_id = $id_arr[count($id_arr) - 1];
1503 $mob_ids[$mob_id] = $mob_id;
1504 }
1505
1506 // determine all inline internal media links
1507 $xpc = xpath_new_context($this->dom);
1508 $path = "//IntLink[@Type = 'MediaObject']";
1509 $res = xpath_eval($xpc, $path);
1510
1511 for($i = 0; $i < count($res->nodeset); $i++)
1512 {
1513 if (($res->nodeset[$i]->get_attribute("TargetFrame") == "") ||
1514 (!$a_inline_only))
1515 {
1516 $target = $res->nodeset[$i]->get_attribute("Target");
1517 $id_arr = explode("_", $target);
1518 if (($id_arr[1] == IL_INST_ID) ||
1519 (substr($target, 0, 4) == "il__"))
1520 {
1521 $mob_id = $id_arr[count($id_arr) - 1];
1522 if (ilObject::_exists($mob_id))
1523 {
1524 $mob_ids[$mob_id] = $mob_id;
1525 }
1526 }
1527 }
1528 }
1529
1530 return $mob_ids;
1531 }
1532
1533
1537 // @todo: can we do this better?
1538 function getInternalLinks($a_cnt_multiple = false)
1539 {
1540 // get all internal links of the page
1541 $xpc = xpath_new_context($this->dom);
1542 $path = "//IntLink";
1543 $res = xpath_eval($xpc, $path);
1544
1545 $links = array();
1546 $cnt_multiple = 1;
1547 for($i = 0; $i < count($res->nodeset); $i++)
1548 {
1549 $add = "";
1550 if ($a_cnt_multiple)
1551 {
1552 $add = ":".$cnt_multiple;
1553 }
1554 $target = $res->nodeset[$i]->get_attribute("Target");
1555 $type = $res->nodeset[$i]->get_attribute("Type");
1556 $targetframe = $res->nodeset[$i]->get_attribute("TargetFrame");
1557 $anchor = $res->nodeset[$i]->get_attribute("Anchor");
1558 $links[$target.":".$type.":".$targetframe.":".$anchor.$add] =
1559 array("Target" => $target, "Type" => $type,
1560 "TargetFrame" => $targetframe, "Anchor" => $anchor);
1561
1562 // get links (image map areas) for inline media objects
1563 if ($type == "MediaObject" && $targetframe == "")
1564 {
1565 if (substr($target, 0, 4) =="il__")
1566 {
1567 $id_arr = explode("_", $target);
1568 $id = $id_arr[count($id_arr) - 1];
1569
1571 foreach($med_links as $key => $med_link)
1572 {
1573 $links[$key] = $med_link;
1574 }
1575 }
1576
1577 }
1578//echo "<br>-:".$target.":".$type.":".$targetframe.":-";
1579 $cnt_multiple++;
1580 }
1581 unset($xpc);
1582
1583 // get all media aliases
1584 $xpc = xpath_new_context($this->dom);
1585 $path = "//MediaAlias";
1586 $res = xpath_eval($xpc, $path);
1587
1588 require_once("Services/MediaObjects/classes/class.ilMediaItem.php");
1589 for($i = 0; $i < count($res->nodeset); $i++)
1590 {
1591 $oid = $res->nodeset[$i]->get_attribute("OriginId");
1592 if (substr($oid, 0, 4) =="il__")
1593 {
1594 $id_arr = explode("_", $oid);
1595 $id = $id_arr[count($id_arr) - 1];
1596
1598 foreach($med_links as $key => $med_link)
1599 {
1600 $links[$key] = $med_link;
1601 }
1602 }
1603 }
1604 unset($xpc);
1605
1606 return $links;
1607 }
1608
1613 // @todo: move to media class
1615 {
1616 $mob_ids = $this->collectMediaObjects();
1617
1618 // get xml of corresponding media objects
1619 $mobs_xml = "";
1620 require_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
1621 foreach($mob_ids as $mob_id => $dummy)
1622 {
1623 if (ilObject::_lookupType($mob_id) == "mob")
1624 {
1625 $mob_obj = new ilObjMediaObject($mob_id);
1626 $mobs_xml .= $mob_obj->getXML(IL_MODE_OUTPUT);
1627 }
1628 }
1629//var_dump($mobs_xml);
1630 return $mobs_xml;
1631 }
1632
1636 // @todo: move to media class
1637 function getMediaAliasElement($a_mob_id, $a_nr = 1)
1638 {
1639 $xpc = xpath_new_context($this->dom);
1640 $path = "//MediaObject/MediaAlias[@OriginId='il__mob_$a_mob_id']";
1641 $res = xpath_eval($xpc, $path);
1642 $mal_node = $res->nodeset[$a_nr - 1];
1643 $mob_node = $mal_node->parent_node();
1644
1645 return $this->dom->dump_node($mob_node);
1646 }
1647
1653 function validateDom()
1654 {
1655 $this->stripHierIDs();
1656
1657 // possible fix for #14820
1658 libxml_disable_entity_loader(false);
1659
1660 @$this->dom->validate($error);
1661 //var_dump($this->dom); exit;
1662 return $error;
1663 }
1664
1680 // @todo: can we do this better? remove dependencies?
1681 function addHierIDs()
1682 {
1683 $this->hier_ids = array();
1684 $this->first_row_ids = array();
1685 $this->first_col_ids = array();
1686 $this->list_item_ids = array();
1687 $this->file_item_ids = array();
1688
1689 // set hierarchical ids for Paragraphs, Tables, TableRows and TableData elements
1690 $xpc = xpath_new_context($this->dom);
1691 //$path = "//Paragraph | //Table | //TableRow | //TableData";
1692
1693 $sep = $path = "";
1694 foreach ($this->id_elements as $el)
1695 {
1696 $path.= $sep."//".$el;
1697 $sep = " | ";
1698 }
1699
1700 $res = xpath_eval($xpc, $path);
1701 for($i = 0; $i < count($res->nodeset); $i++)
1702 {
1703 $cnode = $res->nodeset[$i];
1704 $ctag = $cnode->node_name();
1705
1706 // get hierarchical id of previous sibling
1707 $sib_hier_id = "";
1708 while($cnode = $cnode->previous_sibling())
1709 {
1710 if (($cnode->node_type() == XML_ELEMENT_NODE)
1711 && $cnode->has_attribute("HierId"))
1712 {
1713 $sib_hier_id = $cnode->get_attribute("HierId");
1714 //$sib_hier_id = $id_attr->value();
1715 break;
1716 }
1717 }
1718
1719 if ($sib_hier_id != "") // set id to sibling id "+ 1"
1720 {
1721 require_once("./Services/COPage/classes/class.ilPageContent.php");
1722 $node_hier_id = ilPageContent::incEdId($sib_hier_id);
1723 $res->nodeset[$i]->set_attribute("HierId", $node_hier_id);
1724 $this->hier_ids[] = $node_hier_id;
1725 if ($ctag == "TableData")
1726 {
1727 if (substr($par_hier_id,strlen($par_hier_id)-2) == "_1")
1728 {
1729 $this->first_row_ids[] = $node_hier_id;
1730 }
1731 }
1732 if ($ctag == "ListItem")
1733 {
1734 $this->list_item_ids[] = $node_hier_id;
1735 }
1736 if ($ctag == "FileItem")
1737 {
1738 $this->file_item_ids[] = $node_hier_id;
1739 }
1740 }
1741 else // no sibling -> node is first child
1742 {
1743 // get hierarchical id of next parent
1744 $cnode = $res->nodeset[$i];
1745 $par_hier_id = "";
1746 while($cnode = $cnode->parent_node())
1747 {
1748 if (($cnode->node_type() == XML_ELEMENT_NODE)
1749 && $cnode->has_attribute("HierId"))
1750 {
1751 $par_hier_id = $cnode->get_attribute("HierId");
1752 //$par_hier_id = $id_attr->value();
1753 break;
1754 }
1755 }
1756//echo "<br>par:".$par_hier_id." ($ctag)";
1757 if (($par_hier_id != "") && ($par_hier_id != "pg")) // set id to parent_id."_1"
1758 {
1759 $node_hier_id = $par_hier_id."_1";
1760 $res->nodeset[$i]->set_attribute("HierId", $node_hier_id);
1761 $this->hier_ids[] = $node_hier_id;
1762 if ($ctag == "TableData")
1763 {
1764 $this->first_col_ids[] = $node_hier_id;
1765 if (substr($par_hier_id,strlen($par_hier_id)-2) == "_1")
1766 {
1767 $this->first_row_ids[] = $node_hier_id;
1768 }
1769 }
1770 if ($ctag == "ListItem")
1771 {
1772 $this->list_item_ids[] = $node_hier_id;
1773 }
1774 if ($ctag == "FileItem")
1775 {
1776 $this->file_item_ids[] = $node_hier_id;
1777 }
1778
1779 }
1780 else // no sibling, no parent -> first node
1781 {
1782 $node_hier_id = "1";
1783 $res->nodeset[$i]->set_attribute("HierId", $node_hier_id);
1784 $this->hier_ids[] = $node_hier_id;
1785 }
1786 }
1787 }
1788
1789 // set special hierarchical id "pg" for pageobject
1790 $xpc = xpath_new_context($this->dom);
1791 $path = "//PageObject";
1792 $res = xpath_eval($xpc, $path);
1793 for($i = 0; $i < count($res->nodeset); $i++) // should only be 1
1794 {
1795 $res->nodeset[$i]->set_attribute("HierId", "pg");
1796 $this->hier_ids[] = "pg";
1797 }
1798 unset($xpc);
1799 }
1800
1804 function getHierIds()
1805 {
1806 return $this->hier_ids;
1807 }
1808
1812 // @todo: move to table classes
1814 {
1815 return $this->first_row_ids;
1816 }
1817
1821 // @todo: move to table classes
1823 {
1824 return $this->first_col_ids;
1825 }
1826
1830 // @todo: move to list class
1832 {
1833 return $this->list_item_ids;
1834 }
1835
1839 // @todo: move to file item class
1841 {
1842 return $this->file_item_ids;
1843 }
1844
1848 function stripHierIDs()
1849 {
1850 if(is_object($this->dom))
1851 {
1852 $xpc = xpath_new_context($this->dom);
1853 $path = "//*[@HierId]";
1854 $res = xpath_eval($xpc, $path);
1855 for($i = 0; $i < count($res->nodeset); $i++) // should only be 1
1856 {
1857 if ($res->nodeset[$i]->has_attribute("HierId"))
1858 {
1859 $res->nodeset[$i]->remove_attribute("HierId");
1860 }
1861 }
1862 unset($xpc);
1863 }
1864 }
1865
1869 function getHierIdsForPCIds($a_pc_ids)
1870 {
1871 if (!is_array($a_pc_ids) || count($a_pc_ids) == 0)
1872 {
1873 return array();
1874 }
1875 $ret = array();
1876
1877 if(is_object($this->dom))
1878 {
1879 $xpc = xpath_new_context($this->dom);
1880 $path = "//*[@PCID]";
1881 $res = xpath_eval($xpc, $path);
1882 for($i = 0; $i < count($res->nodeset); $i++) // should only be 1
1883 {
1884 $pc_id = $res->nodeset[$i]->get_attribute("PCID");
1885 if (in_array($pc_id, $a_pc_ids))
1886 {
1887 $ret[$pc_id] = $res->nodeset[$i]->get_attribute("HierId");
1888 }
1889 }
1890 unset($xpc);
1891 }
1892//var_dump($ret);
1893 return $ret;
1894 }
1895
1899 // @todo: move to file item class
1900 function addFileSizes()
1901 {
1902 $xpc = xpath_new_context($this->dom);
1903 $path = "//FileItem";
1904 $res = xpath_eval($xpc, $path);
1905 for($i = 0; $i < count($res->nodeset); $i++)
1906 {
1907 $cnode = $res->nodeset[$i];
1908 $size_node = $this->dom->create_element("Size");
1909 $size_node = $cnode->append_child($size_node);
1910
1911 $childs = $cnode->child_nodes();
1912 $size = "";
1913 for($j = 0; $j < count($childs); $j++)
1914 {
1915 if ($childs[$j]->node_name() == "Identifier")
1916 {
1917 if ($childs[$j]->has_attribute("Entry"))
1918 {
1919 $entry = $childs[$j]->get_attribute("Entry");
1920 $entry_arr = explode("_", $entry);
1921 $id = $entry_arr[count($entry_arr) - 1];
1922 require_once("./Modules/File/classes/class.ilObjFile.php");
1924 }
1925 }
1926 }
1927 $size_node->set_content($size);
1928 }
1929
1930 unset($xpc);
1931 }
1932
1937 // @todo: possible to improve this?
1938 function resolveIntLinks($a_link_map = null)
1939 {
1940 $changed = false;
1941
1942 $this->log->debug("start");
1943
1944 // resolve normal internal links
1945 $xpc = xpath_new_context($this->dom);
1946 $path = "//IntLink";
1947 $res = xpath_eval($xpc, $path);
1948 for($i = 0; $i < count($res->nodeset); $i++)
1949 {
1950 $target = $res->nodeset[$i]->get_attribute("Target");
1951 $type = $res->nodeset[$i]->get_attribute("Type");
1952
1953 if ($a_link_map == null)
1954 {
1955 $new_target = ilInternalLink::_getIdForImportId($type, $target);
1956 $this->log->debug("no map, type: ".$type.", target: ".$target.", new target: ".$new_target);
1957// echo "-".$new_target."-".$type."-".$target."-"; exit;
1958 }
1959 else
1960 {
1961 $nt = explode("_", $a_link_map[$target]);
1962 $new_target = false;
1963 if ($nt[1] == IL_INST_ID)
1964 {
1965 $new_target = "il__".$nt[2]."_".$nt[3];
1966 }
1967 $this->log->debug("map, type: ".$type.", target: ".$target.", new target: ".$new_target);
1968 }
1969 if ($new_target !== false)
1970 {
1971 $res->nodeset[$i]->set_attribute("Target", $new_target);
1972 $changed = true;
1973 }
1974 else // check wether link target is same installation
1975 {
1976 if (ilInternalLink::_extractInstOfTarget($target) == IL_INST_ID &&
1977 IL_INST_ID > 0 && $type != "RepositoryItem")
1978 {
1980 if (ilInternalLink::_exists($type, $new_target))
1981 {
1982 $res->nodeset[$i]->set_attribute("Target", $new_target);
1983 $changed = true;
1984 }
1985 }
1986 }
1987
1988 }
1989 unset($xpc);
1990
1991 // resolve internal links in map areas
1992 $xpc = xpath_new_context($this->dom);
1993 $path = "//MediaAlias";
1994 $res = xpath_eval($xpc, $path);
1995//echo "<br><b>page::resolve</b><br>";
1996//echo "Content:".htmlentities($this->getXMLFromDOM()).":<br>";
1997 for($i = 0; $i < count($res->nodeset); $i++)
1998 {
1999 $orig_id = $res->nodeset[$i]->get_attribute("OriginId");
2000 $id_arr = explode("_", $orig_id);
2001 $mob_id = $id_arr[count($id_arr) - 1];
2003 }
2004 return $changed;
2005 }
2006
2013 // @todo: move to media classes?
2014 function resolveMediaAliases($a_mapping, $a_reuse_existing_by_import = false)
2015 {
2016 // resolve normal internal links
2017 $xpc = xpath_new_context($this->dom);
2018 $path = "//MediaAlias";
2019 $res = xpath_eval($xpc, $path);
2020 $changed = false;
2021 for($i = 0; $i < count($res->nodeset); $i++)
2022 {
2023 // get the ID of the import file from the xml
2024 $old_id = $res->nodeset[$i]->get_attribute("OriginId");
2025 $old_id = explode("_", $old_id);
2026 $old_id = $old_id[count($old_id) - 1];
2027 // get the new id from the current mapping
2028 if ($a_mapping[$old_id] > 0)
2029 {
2030 $new_id = $a_mapping[$old_id];
2031 if ($a_reuse_existing_by_import)
2032 {
2033 // this should work, if the lm has been imported in a translation installation and re-exported
2034 $import_id = ilObject::_lookupImportId($new_id);
2035 $imp = explode("_", $import_id);
2036 if ($imp[1] == IL_INST_ID && $imp[2] == "mob" && ilObject::_lookupType($imp[3]) == "mob")
2037 {
2038 $new_id = $imp[3];
2039 }
2040
2041 // now check, if the translation has been done just by changing text in the exported
2042 // translation file
2043 if ($import_id == "")
2044 {
2045 // if the old_id is also referred by the page content of the default language
2046 // we assume that this media object is unchanged
2047 include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
2048 $med_of_def_lang = ilObjMediaObject::_getMobsOfObject("lm:pg", $this->getId(), 0, "-");
2049 if (in_array($old_id, $med_of_def_lang))
2050 {
2051 $new_id = $old_id;
2052 }
2053 }
2054 }
2055
2056 $res->nodeset[$i]->set_attribute("OriginId", "il__mob_".$new_id);
2057 $changed = true;
2058 }
2059 }
2060 unset($xpc);
2061
2062 return $changed;
2063 }
2064
2071 // @todo: move to iim classes?
2072 function resolveIIMMediaAliases($a_mapping)
2073 {
2074 // resolve normal internal links
2075 $xpc = xpath_new_context($this->dom);
2076 $path = "//InteractiveImage/MediaAlias";
2077 $res = xpath_eval($xpc, $path);
2078 $changed = false;
2079 for($i = 0; $i < count($res->nodeset); $i++)
2080 {
2081 $old_id = $res->nodeset[$i]->get_attribute("OriginId");
2082 if ($a_mapping[$old_id] > 0)
2083 {
2084 $res->nodeset[$i]->set_attribute("OriginId", "il__mob_".$a_mapping[$old_id]);
2085 $changed = true;
2086 }
2087 }
2088 unset($xpc);
2089
2090 return $changed;
2091 }
2092
2099 // @todo: move to file classes?
2100 function resolveFileItems($a_mapping)
2101 {
2102 // resolve normal internal links
2103 $xpc = xpath_new_context($this->dom);
2104 $path = "//FileItem/Identifier";
2105 $res = xpath_eval($xpc, $path);
2106 $changed = false;
2107 for($i = 0; $i < count($res->nodeset); $i++)
2108 {
2109 $old_id = $res->nodeset[$i]->get_attribute("Entry");
2110 $old_id = explode("_", $old_id);
2111 $old_id = $old_id[count($old_id) - 1];
2112 if ($a_mapping[$old_id] > 0)
2113 {
2114 $res->nodeset[$i]->set_attribute("Entry", "il__file_".$a_mapping[$old_id]);
2115 $changed = true;
2116 }
2117 }
2118 unset($xpc);
2119
2120 return $changed;
2121 }
2122
2127 // @todo: move to question classes
2128 function resolveQuestionReferences($a_mapping)
2129 {
2130 // resolve normal internal links
2131 $xpc = xpath_new_context($this->dom);
2132 $path = "//Question";
2133 $res = xpath_eval($xpc, $path);
2134 $updated = false;
2135 for($i = 0; $i < count($res->nodeset); $i++)
2136 {
2137 $qref = $res->nodeset[$i]->get_attribute("QRef");
2138
2139 if (isset($a_mapping[$qref]))
2140 {
2141 $res->nodeset[$i]->set_attribute("QRef", "il__qst_".$a_mapping[$qref]["pool"]);
2142 $updated = true;
2143 }
2144 }
2145 unset($xpc);
2146
2147 return $updated;
2148 }
2149
2150
2157 // @todo: generalize, internal links usage info
2158 function moveIntLinks($a_from_to)
2159 {
2160 $this->buildDom();
2161
2162 $changed = false;
2163
2164 // resolve normal internal links
2165 $xpc = xpath_new_context($this->dom);
2166 $path = "//IntLink";
2167 $res = xpath_eval($xpc, $path);
2168 for($i = 0; $i < count($res->nodeset); $i++)
2169 {
2170 $target = $res->nodeset[$i]->get_attribute("Target");
2171 $type = $res->nodeset[$i]->get_attribute("Type");
2173 if ($a_from_to[$obj_id] > 0 && is_int(strpos($target, "__")))
2174 {
2175 if ($type == "PageObject" && ilLMObject::_lookupType($a_from_to[$obj_id]) == "pg")
2176 {
2177 $res->nodeset[$i]->set_attribute("Target", "il__pg_".$a_from_to[$obj_id]);
2178 $changed = true;
2179 }
2180 if ($type == "StructureObject" && ilLMObject::_lookupType($a_from_to[$obj_id]) == "st")
2181 {
2182 $res->nodeset[$i]->set_attribute("Target", "il__st_".$a_from_to[$obj_id]);
2183 $changed = true;
2184 }
2185 }
2186 }
2187 unset($xpc);
2188
2189 // map areas
2190 $this->addHierIDs();
2191 $xpc = xpath_new_context($this->dom);
2192 $path = "//MediaAlias";
2193 $res = xpath_eval($xpc, $path);
2194
2195 require_once("Services/MediaObjects/classes/class.ilMediaItem.php");
2196 require_once("Services/COPage/classes/class.ilMediaAliasItem.php");
2197
2198 for($i = 0; $i < count($res->nodeset); $i++)
2199 {
2200 $media_object_node = $res->nodeset[$i]->parent_node();
2201 $page_content_node = $media_object_node->parent_node();
2202 $c_hier_id = $page_content_node->get_attribute("HierId");
2203
2204 // first check, wheter we got instance map areas -> take these
2205 $std_alias_item = new ilMediaAliasItem($this->dom,
2206 $c_hier_id, "Standard");
2207 $areas = $std_alias_item->getMapAreas();
2208 $correction_needed = false;
2209 if (count($areas) > 0)
2210 {
2211 // check if correction needed
2212 foreach($areas as $area)
2213 {
2214 if ($area["Type"] == "PageObject" ||
2215 $area["Type"] == "StructureObject")
2216 {
2217 $t = $area["Target"];
2218 $tid = _extractObjIdOfTarget($t);
2219 if ($a_from_to[$tid] > 0)
2220 {
2221 $correction_needed = true;
2222 }
2223 }
2224 }
2225 }
2226 else
2227 {
2228 $areas = array();
2229
2230 // get object map areas and check whether at least one must
2231 // be corrected
2232 $oid = $res->nodeset[$i]->get_attribute("OriginId");
2233 if (substr($oid, 0, 4) =="il__")
2234 {
2235 $id_arr = explode("_", $oid);
2236 $id = $id_arr[count($id_arr) - 1];
2237
2238 $mob = new ilObjMediaObject($id);
2239 $med_item = $mob->getMediaItem("Standard");
2240 $med_areas = $med_item->getMapAreas();
2241
2242 foreach($med_areas as $area)
2243 {
2244 $link_type = ($area->getLinkType() == "int")
2245 ? "IntLink"
2246 : "ExtLink";
2247
2248 $areas[] = array(
2249 "Nr" => $area->getNr(),
2250 "Shape" => $area->getShape(),
2251 "Coords" => $area->getCoords(),
2252 "Link" => array(
2253 "LinkType" => $link_type,
2254 "Href" => $area->getHref(),
2255 "Title" => $area->getTitle(),
2256 "Target" => $area->getTarget(),
2257 "Type" => $area->getType(),
2258 "TargetFrame" => $area->getTargetFrame()
2259 )
2260 );
2261
2262 if ($area->getType() == "PageObject" ||
2263 $area->getType() == "StructureObject")
2264 {
2265 $t = $area->getTarget();
2267 if ($a_from_to[$tid] > 0)
2268 {
2269 $correction_needed = true;
2270 }
2271//var_dump($a_from_to);
2272 }
2273 }
2274 }
2275 }
2276
2277 // correct map area links
2278 if ($correction_needed)
2279 {
2280 $changed = true;
2281 $std_alias_item->deleteAllMapAreas();
2282 foreach($areas as $area)
2283 {
2284 if ($area["Link"]["LinkType"] == "IntLink")
2285 {
2286 $target = $area["Link"]["Target"];
2287 $type = $area["Link"]["Type"];
2289 if ($a_from_to[$obj_id] > 0)
2290 {
2291 if ($type == "PageObject" && ilLMObject::_lookupType($a_from_to[$obj_id]) == "pg")
2292 {
2293 $area["Link"]["Target"] = "il__pg_".$a_from_to[$obj_id];
2294 }
2295 if ($type == "StructureObject" && ilLMObject::_lookupType($a_from_to[$obj_id]) == "st")
2296 {
2297 $area["Link"]["Target"] = "il__st_".$a_from_to[$obj_id];
2298 }
2299 }
2300 }
2301
2302 $std_alias_item->addMapArea($area["Shape"], $area["Coords"],
2303 $area["Link"]["Title"],
2304 array( "Type" => $area["Link"]["Type"],
2305 "TargetFrame" => $area["Link"]["TargetFrame"],
2306 "Target" => $area["Link"]["Target"],
2307 "Href" => $area["Link"]["Href"],
2308 "LinkType" => $area["Link"]["LinkType"],
2309 ));
2310 }
2311 }
2312 }
2313 unset($xpc);
2314
2315 return $changed;
2316 }
2317
2323 // @todo: generalize, internal links usage info
2324 static function _handleImportRepositoryLinks($a_rep_import_id, $a_rep_type, $a_rep_ref_id)
2325 {
2326 include_once("./Services/Link/classes/class.ilInternalLink.php");
2327
2328//echo "-".$a_rep_import_id."-".$a_rep_ref_id."-";
2329 $sources = ilInternalLink::_getSourcesOfTarget("obj",
2330 ilInternalLink::_extractObjIdOfTarget($a_rep_import_id),
2331 ilInternalLink::_extractInstOfTarget($a_rep_import_id));
2332//var_dump($sources);
2333 foreach($sources as $source)
2334 {
2335//echo "A";
2336 if ($source["type"] == "lm:pg")
2337 {
2338//echo "B";
2339 include_once("./Modules/LearningModule/classes/class.ilLMPage.php");
2340 if (self::_exists("lm", $source["id"], $source["lang"]))
2341 {
2342 $page_obj = new ilLMPage($source["id"], 0, $source["lang"]);
2343 if (!$page_obj->page_not_found)
2344 {
2345 //echo "C";
2346 $page_obj->handleImportRepositoryLink($a_rep_import_id,
2347 $a_rep_type, $a_rep_ref_id);
2348 }
2349 $page_obj->update();
2350 }
2351 }
2352 }
2353 }
2354
2355 // @todo: generalize, internal links usage info
2356 function handleImportRepositoryLink($a_rep_import_id, $a_rep_type, $a_rep_ref_id)
2357 {
2358 $this->buildDom();
2359
2360 // resolve normal internal links
2361 $xpc = xpath_new_context($this->dom);
2362 $path = "//IntLink";
2363 $res = xpath_eval($xpc, $path);
2364//echo "1";
2365 for($i = 0; $i < count($res->nodeset); $i++)
2366 {
2367//echo "2";
2368 $target = $res->nodeset[$i]->get_attribute("Target");
2369 $type = $res->nodeset[$i]->get_attribute("Type");
2370 if ($target == $a_rep_import_id && $type == "RepositoryItem")
2371 {
2372//echo "setting:"."il__".$a_rep_type."_".$a_rep_ref_id;
2373 $res->nodeset[$i]->set_attribute("Target",
2374 "il__".$a_rep_type."_".$a_rep_ref_id);
2375 }
2376 }
2377 unset($xpc);
2378 }
2379
2386 function handleRepositoryLinksOnCopy($a_mapping, $a_source_ref_id)
2387 {
2388 global $tree;
2389
2390 $this->buildDom();
2391 $this->log->debug("Handle repository links...");
2392
2393 // resolve normal internal links
2394 $xpc = xpath_new_context($this->dom);
2395 $path = "//IntLink";
2396 $res = xpath_eval($xpc, $path);
2397 for($i = 0; $i < count($res->nodeset); $i++)
2398 {
2399 $target = $res->nodeset[$i]->get_attribute("Target");
2400 $type = $res->nodeset[$i]->get_attribute("Type");
2401 $this->log->debug("Target: ".$target);
2402 $t = explode("_", $target);
2403 if ($type == "RepositoryItem" && ((int) $t[1] == 0 || (int) $t[1] == IL_INST_ID))
2404 {
2405 if (isset($a_mapping[$t[3]]))
2406 {
2407 // we have a mapping -> replace the ID
2408 $this->log->debug("... replace " . $t[3] . " with " . $a_mapping[$t[3]] . ".");
2409 $res->nodeset[$i]->set_attribute("Target",
2410 "il__obj_" . $a_mapping[$t[3]]);
2411 }
2412 else if ($tree->isGrandChild($a_source_ref_id, $t[3]))
2413 {
2414 // we have no mapping, but the linked object is child of the original node -> remove link
2415 $this->log->debug("... remove links.");
2416 if ($res->nodeset[$i]->parent_node()->node_name() == "MapArea") // simply remove map areas
2417 {
2418 $parent = $res->nodeset[$i]->parent_node();
2419 $parent->unlink_node($parent);
2420 }
2421 else // replace link by content of the link for other internal links
2422 {
2423 $source_node = $res->nodeset[$i];
2424 $new_node = $source_node->clone_node(true);
2425 $new_node->unlink_node($new_node);
2426 $childs = $new_node->child_nodes();
2427 for ($j = 0; $j < count($childs); $j++)
2428 {
2429 $this->log->debug("... move node $j " . $childs[$j]->node_name() . " before " . $source_node->node_name());
2430 $source_node->insert_before($childs[$j], $source_node);
2431 }
2432 $source_node->unlink_node($source_node);
2433 }
2434 }
2435 }
2436 }
2437 unset($xpc);
2438 }
2439
2440
2444 function createFromXML()
2445 {
2446 global $lng, $ilDB, $ilUser;
2447
2448//echo "<br>PageObject::createFromXML[".$this->getId()."]";
2449
2450 $empty = false;
2451 if($this->getXMLContent() == "")
2452 {
2453 $this->setXMLContent("<PageObject></PageObject>");
2454 $empty = true;
2455 }
2456
2457 $content = $this->getXMLContent();
2458 $this->buildDom(true);
2459 $dom_doc = $this->getDomDoc();
2460
2461 $iel = $this->containsDeactivatedElements($content);
2462 $inl = $this->containsIntLinks($content);
2463
2464 // create object
2465 $ilDB->insert("page_object", array(
2466 "page_id" => array("integer", $this->getId()),
2467 "parent_id" => array("integer", $this->getParentId()),
2468 "lang" => array("text", $this->getLanguage()),
2469 "content" => array("clob", $content),
2470 "parent_type" => array("text", $this->getParentType()),
2471 "create_user" => array("integer", $ilUser->getId()),
2472 "last_change_user" => array("integer", $ilUser->getId()),
2473 "active" => array("integer", (int) $this->getActive()),
2474 "activation_start" => array("timestamp", $this->getActivationStart()),
2475 "activation_end" => array("timestamp", $this->getActivationEnd()),
2476 "show_activation_info" => array("integer", (int) $this->getShowActivationInfo()),
2477 "inactive_elements" => array("integer", $iel),
2478 "int_links" => array("integer", $inl),
2479 "created" => array("timestamp", ilUtil::now()),
2480 "last_change" => array("timestamp", ilUtil::now())
2481 ));
2482
2483 // after update event
2484 $this->__afterUpdate($dom_doc, $content, true, $empty);
2485
2486 }
2487
2488
2497 function updateFromXML()
2498 {
2499 global $lng, $ilDB, $ilUser;
2500
2501 $this->log->debug("ilPageObject, updateFromXML(): start, id: ".$this->getId());
2502
2503//echo "<br>PageObject::updateFromXML[".$this->getId()."]";
2504//echo "update:".ilUtil::prepareDBString(($this->getXMLContent())).":<br>";
2505//echo "update:".htmlentities($this->getXMLContent()).":<br>";
2506
2507 $content = $this->getXMLContent();
2508
2509 $this->log->debug("ilPageObject, updateFromXML(): content: ".substr($content, 0, 100));
2510
2511 $this->buildDom(true);
2512 $dom_doc = $this->getDomDoc();
2513
2514 $iel = $this->containsDeactivatedElements($content);
2515 $inl = $this->containsIntLinks($content);
2516
2517 $ilDB->update("page_object", array(
2518 "content" => array("clob", $content),
2519 "parent_id" => array("integer", $this->getParentId()),
2520 "last_change_user" => array("integer", $ilUser->getId()),
2521 "last_change" => array("timestamp", ilUtil::now()),
2522 "active" => array("integer", $this->getActive()),
2523 "activation_start" => array("timestamp", $this->getActivationStart()),
2524 "activation_end" => array("timestamp", $this->getActivationEnd()),
2525 "inactive_elements" => array("integer", $iel),
2526 "int_links" => array("integer", $inl),
2527 ), array(
2528 "page_id" => array("integer", $this->getId()),
2529 "parent_type" => array("text", $this->getParentType()),
2530 "lang" => array("text", $this->getLanguage())
2531 ));
2532
2533 // after update event
2534 $this->__afterUpdate($dom_doc, $content);
2535
2536 $this->log->debug("ilPageObject, updateFromXML(): end");
2537
2538 return true;
2539 }
2540
2547 protected final function __afterUpdate($a_domdoc, $a_xml, $a_creation = false, $a_empty = false)
2548 {
2549 // we do not need this if we are creating an empty page
2550 if (!$a_creation || !$a_empty)
2551 {
2552 // save internal link information
2553 // the page object is responsible to do this, since it "offers" the
2554 // internal link feature pc and page classes
2555 $this->saveInternalLinks($a_domdoc);
2556
2557 // save style usage
2558 $this->saveStyleUsage($a_domdoc);
2559
2560 // pc classes hook
2561 include_once("./Services/COPage/classes/class.ilCOPagePCDef.php");
2563 foreach ($defs as $def)
2564 {
2566 $cl = $def["pc_class"];
2567 call_user_func($def["pc_class"].'::afterPageUpdate', $this, $a_domdoc, $a_xml, $a_creation);
2568 }
2569 }
2570
2571 // call page hook
2572 $this->afterUpdate($a_domdoc, $a_xml);
2573
2574 // call update listeners
2575 $this->callUpdateListeners();
2576 }
2577
2584 function afterUpdate()
2585 {
2586 }
2587
2588
2593 function update($a_validate = true, $a_no_history = false)
2594 {
2595 global $lng, $ilDB, $ilUser, $ilLog, $ilCtrl;
2596
2597 $this->log->debug("ilPageObject, update(): start, id: ".$this->getId());
2598
2599 $lm_set = new ilSetting("lm");
2600
2601//echo "<br>**".$this->getId()."**";
2602//echo "<br>PageObject::update[".$this->getId()."],validate($a_validate)";
2603//echo "\n<br>dump_all2:".$this->dom->dump_mem(0, "UTF-8").":";
2604//echo "\n<br>PageObject::update:".$this->getXMLFromDom().":";
2605//debug_print_backtrace();
2606//echo "<br>PageObject::update:".htmlentities($this->getXMLFromDom()); exit;
2607
2608 // add missing pc ids
2609 if (!$this->checkPCIds())
2610 {
2611 $this->insertPCIds();
2612 }
2613
2614 // test validating
2615 if($a_validate)
2616 {
2617 $errors = $this->validateDom();
2618 }
2619//var_dump($errors); exit;
2620 if (empty($errors) && !$this->getEditLock())
2621 {
2622 include_once("./Services/User/classes/class.ilUserUtil.php");
2623 $lock = $this->getEditLockInfo();
2624 $errors[0] = array(0 => 0,
2625 1 => "nocontent#".$lng->txt("cont_not_saved_edit_lock_expired")."<br />".
2626 $lng->txt("obj_usr").": ".
2627 ilUserUtil::getNamePresentation($lock["edit_lock_user"])."<br />".
2628 $lng->txt("content_until").": ".
2629 ilDatePresentation::formatDate(new ilDateTime($lock["edit_lock_until"],IL_CAL_UNIX))
2630 );
2631 }
2632
2633 if (!empty($errors))
2634 {
2635 $this->log->debug("ilPageObject, update(): errors: ".print_r($errors, true));
2636 }
2637
2638//echo "-".htmlentities($this->getXMLFromDom())."-"; exit;
2639 if(empty($errors))
2640 {
2641 // @todo 1: is this page type or pc content type
2642 // related -> plugins should be able to hook in!?
2644
2645 // get xml content
2646 $content = $this->getXMLFromDom();
2647 $dom_doc = $this->getDomDoc();
2648
2649 // this needs to be locked
2650
2651 // write history entry
2652 $old_set = $ilDB->query("SELECT * FROM page_object WHERE ".
2653 "page_id = ".$ilDB->quote($this->getId(), "integer")." AND ".
2654 "parent_type = ".$ilDB->quote($this->getParentType(), "text")." AND ".
2655 "lang = ".$ilDB->quote($this->getLanguage(), "text"));
2656 $last_nr_set = $ilDB->query("SELECT max(nr) as mnr FROM page_history WHERE ".
2657 "page_id = ".$ilDB->quote($this->getId(), "integer")." AND ".
2658 "parent_type = ".$ilDB->quote($this->getParentType(), "text")." AND ".
2659 "lang = ".$ilDB->quote($this->getLanguage(), "text"));
2660 $last_nr = $ilDB->fetchAssoc($last_nr_set);
2661 if ($old_rec = $ilDB->fetchAssoc($old_set))
2662 {
2663 // only save, if something has changed
2664 // added user id to the check for ilias 5.0, 7.10.2014
2665 if (($content != $old_rec["content"] || $ilUser->getId() != $old_rec["last_change_user"]) &&
2666 !$a_no_history && !$this->history_saved && $lm_set->get("page_history", 1))
2667 {
2668 if ($old_rec["content"] != "<PageObject></PageObject>")
2669 {
2670 $ilDB->manipulateF("DELETE FROM page_history WHERE ".
2671 "page_id = %s AND parent_type = %s AND hdate = %s AND lang = %s",
2672 array("integer", "text", "timestamp", "text"),
2673 array($old_rec["page_id"], $old_rec["parent_type"], $old_rec["last_change"], $old_rec["lang"]));
2674
2675 // the following lines are a workaround for
2676 // bug 6741
2677 $last_c = $old_rec["last_change"];
2678 if ($last_c == "")
2679 {
2680 $last_c = ilUtil::now();
2681 }
2682
2683 $ilDB->insert("page_history", array(
2684 "page_id" => array("integer", $old_rec["page_id"]),
2685 "parent_type" => array("text", $old_rec["parent_type"]),
2686 "lang" => array("text", $old_rec["lang"]),
2687 "hdate" => array("timestamp", $last_c),
2688 "parent_id" => array("integer", $old_rec["parent_id"]),
2689 "content" => array("clob", $old_rec["content"]),
2690 "user_id" => array("integer", $old_rec["last_change_user"]),
2691 "ilias_version" => array("text", ILIAS_VERSION_NUMERIC),
2692 "nr" => array("integer", (int) $last_nr["mnr"] + 1)
2693 ));
2694
2695 $old_content = $old_rec["content"];
2696 $old_domdoc = new DOMDocument();
2697 $old_nr = $last_nr["mnr"] + 1;
2698 $old_domdoc->loadXML('<?xml version="1.0" encoding="UTF-8"?>'.$old_content);
2699
2700 // after history entry creation event
2701 $this->__afterHistoryEntry($old_domdoc, $old_content, $old_nr);
2702
2703 $this->history_saved = true; // only save one time
2704 }
2705 else
2706 {
2707 $this->history_saved = true; // do not save on first change
2708 }
2709 }
2710 }
2711//echo htmlentities($content);
2712 $em = (trim($content) == "<PageObject/>")
2713 ? 1
2714 : 0;
2715
2716 // @todo: pass dom instead?
2717 $iel = $this->containsDeactivatedElements($content);
2718 $inl = $this->containsIntLinks($content);
2719
2720 $ilDB->update("page_object", array(
2721 "content" => array("clob", $content),
2722 "parent_id" => array("integer", $this->getParentId()),
2723 "last_change_user" => array("integer", $ilUser->getId()),
2724 "last_change" => array("timestamp", ilUtil::now()),
2725 "is_empty" => array("integer", $em),
2726 "active" => array("integer", $this->getActive()),
2727 "activation_start" => array("timestamp", $this->getActivationStart()),
2728 "activation_end" => array("timestamp", $this->getActivationEnd()),
2729 "show_activation_info" => array("integer", $this->getShowActivationInfo()),
2730 "inactive_elements" => array("integer", $iel),
2731 "int_links" => array("integer", $inl),
2732 ), array(
2733 "page_id" => array("integer", $this->getId()),
2734 "parent_type" => array("text", $this->getParentType()),
2735 "lang" => array("text", $this->getLanguage())
2736 ));
2737
2738 // after update event
2739 $this->__afterUpdate($dom_doc, $content);
2740
2741 $this->log->debug("ilPageObject, update(): updated and returning true, content: ".substr($this->getXMLContent(), 0, 100));
2742
2743//echo "<br>PageObject::update:".htmlentities($this->getXMLContent()).":";
2744 return true;
2745 }
2746 else
2747 {
2748 return $errors;
2749 }
2750 }
2751
2752
2753
2757 function delete()
2758 {
2759 global $ilDB;
2760
2761 $copg_logger = ilLoggerFactory::getLogger('copg');
2762 $copg_logger->debug("ilPageObject: Delete called for ID '".$this->getId()."',".
2763 " parent type: '".$this->getParentType()."', ".
2764 " hist nr: '".$this->old_nr."', ".
2765 " lang: '".$this->getLanguage()."', "
2766 );
2767
2768 $mobs = array();
2769 $files = array();
2770
2771 if (!$this->page_not_found)
2772 {
2773 $this->buildDom();
2774 $mobs = $this->collectMediaObjects(false);
2775 }
2776 include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
2777 $mobs2 = ilObjMediaObject::_getMobsOfObject($this->getParentType().":pg", $this->getId(), false);
2778 foreach ($mobs2 as $m)
2779 {
2780 if (!in_array($m, $mobs))
2781 {
2782 $mobs[] = $m;
2783 }
2784 }
2785
2786 $copg_logger->debug("ilPageObject: ... found ".count($mobs)." media objects.");
2787
2788 $this->__beforeDelete();
2789
2790 // delete style usages
2791 $this->deleteStyleUsages(false);
2792
2793 // delete internal links
2794 $this->deleteInternalLinks();
2795
2796 // delete all mob usages
2797 ilObjMediaObject::_deleteAllUsages($this->getParentType().":pg", $this->getId());
2798
2799 // delete news
2800 include_once("./Services/News/classes/class.ilNewsItem.php");
2802 $this->getParentType(), $this->getId(), "pg");
2803
2804 // delete page_object entry
2805 $ilDB->manipulate("DELETE FROM page_object ".
2806 "WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
2807 " AND parent_type= ".$ilDB->quote($this->getParentType(), "text"));
2808 //$this->ilias->db->query($query);
2809
2810 // delete media objects
2811 foreach ($mobs as $mob_id)
2812 {
2813 $copg_logger->debug("ilPageObject: ... processing mob ".$mob_id.".");
2814
2815 if(ilObject::_lookupType($mob_id) != 'mob')
2816 {
2817 $copg_logger->debug("ilPageObject: ... type mismatch. Ignoring mob ".$mob_id.".");
2818 continue;
2819 }
2820
2821 if (ilObject::_exists($mob_id))
2822 {
2823 $copg_logger->debug("ilPageObject: ... delete mob ".$mob_id.".");
2824
2825 $mob_obj = new ilObjMediaObject($mob_id);
2826 $mob_obj->delete();
2827 }
2828 else
2829 {
2830 $copg_logger->debug("ilPageObject: ... missing mob ".$mob_id.".");
2831 }
2832 }
2833
2834
2835 /* delete public and private notes (see PageObjectGUI->getNotesHTML())
2836 as they can be seen as personal data we are keeping them for now
2837 include_once("Services/Notes/classes/class.ilNote.php");
2838 foreach(array(IL_NOTE_PRIVATE, IL_NOTE_PUBLIC) as $note_type)
2839 {
2840 foreach(ilNote::_getNotesOfObject($this->getParentId(), $this->getId(),
2841 $this->getParentType(), $note_type) as $note)
2842 {
2843 $note->delete();
2844 }
2845 }
2846 */
2847 }
2848
2854 protected final function __beforeDelete()
2855 {
2856 // pc classes hook
2857 include_once("./Services/COPage/classes/class.ilCOPagePCDef.php");
2859 foreach ($defs as $def)
2860 {
2862 $cl = $def["pc_class"];
2863 call_user_func($def["pc_class"].'::beforePageDelete', $this);
2864 }
2865 }
2866
2872 protected final function __afterHistoryEntry($a_old_domdoc, $a_old_content, $a_old_nr)
2873 {
2874 // save style usage
2875 $this->saveStyleUsage($a_old_domdoc, $a_old_nr);
2876
2877 // pc classes hook
2878 include_once("./Services/COPage/classes/class.ilCOPagePCDef.php");
2880 foreach ($defs as $def)
2881 {
2883 $cl = $def["pc_class"];
2884 call_user_func($def["pc_class"].'::afterPageHistoryEntry', $this, $a_old_domdoc, $a_old_content, $a_old_nr);
2885 }
2886 }
2887
2893 function saveStyleUsage($a_domdoc, $a_old_nr = 0)
2894 {
2895 global $ilDB;
2896
2897 // media aliases
2898 $xpath = new DOMXPath($a_domdoc);
2899 $path = "//Paragraph | //Section | //MediaAlias | //FileItem".
2900 " | //Table | //TableData | //Tabs | //List";
2901 $nodes = $xpath->query($path);
2902 $usages = array();
2903 foreach($nodes as $node)
2904 {
2905 switch ($node->localName)
2906 {
2907 case "Paragraph":
2908 $sname = $node->getAttribute("Characteristic");
2909 $stype = "text_block";
2910 $template = 0;
2911 break;
2912
2913 case "Section":
2914 $sname = $node->getAttribute("Characteristic");
2915 $stype = "section";
2916 $template = 0;
2917 break;
2918
2919 case "MediaAlias":
2920 $sname = $node->getAttribute("Class");
2921 $stype = "media_cont";
2922 $template = 0;
2923 break;
2924
2925 case "FileItem":
2926 $sname = $node->getAttribute("Class");
2927 $stype = "flist_li";
2928 $template = 0;
2929 break;
2930
2931 case "Table":
2932 $sname = $node->getAttribute("Template");
2933 if ($sname == "")
2934 {
2935 $sname = $node->getAttribute("Class");
2936 $stype = "table";
2937 $template = 0;
2938 }
2939 else
2940 {
2941 $stype = "table";
2942 $template = 1;
2943 }
2944 break;
2945
2946 case "TableData":
2947 $sname = $node->getAttribute("Class");
2948 $stype = "table_cell";
2949 $template = 0;
2950 break;
2951
2952 case "Tabs":
2953 $sname = $node->getAttribute("Template");
2954 if ($sname != "")
2955 {
2956 if ($node->getAttribute("Type") == "HorizontalAccordion")
2957 {
2958 $stype = "haccordion";
2959 }
2960 if ($node->getAttribute("Type") == "VerticalAccordion")
2961 {
2962 $stype = "vaccordion";
2963 }
2964 }
2965 $template = 1;
2966 break;
2967
2968 case "List":
2969 $sname = $node->getAttribute("Class");
2970 if ($node->getAttribute("Type") == "Ordered")
2971 {
2972 $stype = "list_o";
2973 }
2974 else
2975 {
2976 $stype = "list_u";
2977 }
2978 $template = 0;
2979 break;
2980 }
2981 if ($sname != "" && $stype != "")
2982 {
2983 $usages[$sname.":".$stype.":".$template] = array("sname" => $sname,
2984 "stype" => $stype, "template" => $template);
2985 }
2986 }
2987
2988
2989 $this->deleteStyleUsages($a_old_nr);
2990
2991 foreach ($usages as $u)
2992 {
2993 $id = $ilDB->nextId('page_style_usage');
2994
2995 $ilDB->manipulate("INSERT INTO page_style_usage ".
2996 "(id, page_id, page_type, page_lang, page_nr, template, stype, sname) VALUES (".
2997 $ilDB->quote($id, "integer").",".
2998 $ilDB->quote($this->getId(), "integer").",".
2999 $ilDB->quote($this->getParentType(), "text").",".
3000 $ilDB->quote($this->getLanguage(), "text").",".
3001 $ilDB->quote($a_old_nr, "integer").",".
3002 $ilDB->quote($u["template"], "integer").",".
3003 $ilDB->quote($u["stype"], "text").",".
3004 $ilDB->quote($u["sname"], "text").
3005 ")");
3006 }
3007 }
3008
3015 function deleteStyleUsages($a_old_nr = 0)
3016 {
3017 global $ilDB;
3018
3019 if ($a_old_nr !== false)
3020 {
3021 $and_old_nr = " AND page_nr = ".$ilDB->quote($a_old_nr, "integer");
3022 }
3023
3024 $ilDB->manipulate("DELETE FROM page_style_usage WHERE ".
3025 " page_id = ".$ilDB->quote($this->getId(), "integer").
3026 " AND page_type = ".$ilDB->quote($this->getParentType(), "text").
3027 " AND page_lang = ".$ilDB->quote($this->getLanguage(), "text").
3028 $and_old_nr
3029 );
3030 }
3031
3032
3037 // @todo: move to content include class
3039 {
3040 include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
3041 include_once("./Modules/File/classes/class.ilObjFile.php");
3043 $this->getId());
3045 $this->getId());
3046 $objs = array_merge($mobs, $files);
3048 }
3049
3057 {
3058 include_once("./Services/Link/classes/class.ilInternalLink.php");
3060 $this->getLanguage());
3061 }
3062
3063
3069 // @todo: move to specific classes, internal link use info
3070 function saveInternalLinks($a_domdoc)
3071 {
3072 global $ilDB;
3073
3074 $this->deleteInternalLinks();
3075
3076 // query IntLink elements
3077 $xpath = new DOMXPath($a_domdoc);
3078 $nodes = $xpath->query('//IntLink');
3079 foreach($nodes as $node)
3080 {
3081 $link_type = $node->getAttribute("Type");
3082
3083 switch ($link_type)
3084 {
3085 case "StructureObject":
3086 $t_type = "st";
3087 break;
3088
3089 case "PageObject":
3090 $t_type = "pg";
3091 break;
3092
3093 case "GlossaryItem":
3094 $t_type = "git";
3095 break;
3096
3097 case "MediaObject":
3098 $t_type = "mob";
3099 break;
3100
3101 case "RepositoryItem":
3102 $t_type = "obj";
3103 break;
3104
3105 case "File":
3106 $t_type = "file";
3107 break;
3108
3109 case "WikiPage":
3110 $t_type = "wpage";
3111 break;
3112
3113 case "User":
3114 $t_type = "user";
3115 break;
3116 }
3117
3118 $target = $node->getAttribute("Target");
3119 $target_arr = explode("_", $target);
3120 $t_id = $target_arr[count($target_arr) - 1];
3121
3122 // link to other internal object
3123 if (is_int(strpos($target, "__")))
3124 {
3125 $t_inst = 0;
3126 }
3127 else // link to unresolved object in other installation
3128 {
3129 $t_inst = $target_arr[1];
3130 }
3131
3132 if ($t_id > 0)
3133 {
3134 ilInternalLink::_saveLink($this->getParentType().":pg", $this->getId(), $t_type,
3135 $t_id, $t_inst, $this->getLanguage());
3136 }
3137 }
3138 }
3139
3143 function create()
3144 {
3145 $this->createFromXML();
3146 }
3147
3155 function deleteContent($a_hid, $a_update = true, $a_pcid = "")
3156 {
3157 $curr_node = $this->getContentNode($a_hid, $a_pcid);
3158 $curr_node->unlink_node($curr_node);
3159 if ($a_update)
3160 {
3161 return $this->update();
3162 }
3163 }
3164
3165
3173 function deleteContents($a_hids, $a_update = true, $a_self_ass = false)
3174 {
3175 if (!is_array($a_hids))
3176 {
3177 return;
3178 }
3179 foreach($a_hids as $a_hid)
3180 {
3181 $a_hid = explode(":", $a_hid);
3182//echo "-".$a_hid[0]."-".$a_hid[1]."-";
3183
3184// @todo 1: hook
3185 // do not delete question nodes in assessment pages
3186 if (!$this->checkForTag("Question", $a_hid[0], $a_hid[1]) || $a_self_ass)
3187 {
3188 $curr_node = $this->getContentNode($a_hid[0], $a_hid[1]);
3189 if (is_object($curr_node))
3190 {
3191 $parent_node = $curr_node->parent_node();
3192 if ($parent_node->node_name() != "TableRow")
3193 {
3194 $curr_node->unlink_node($curr_node);
3195 }
3196 }
3197 }
3198 }
3199 if ($a_update)
3200 {
3201 return $this->update();
3202 }
3203 }
3204
3210 function cutContents($a_hids)
3211 {
3212 $this->copyContents($a_hids);
3213 return $this->deleteContents($a_hids, true, $this->getPageConfig()->getEnableSelfAssessment());
3214 }
3215
3221 function copyContents($a_hids)
3222 {
3223 global $ilUser;
3224//var_dump($a_hids);
3225 if (!is_array($a_hids))
3226 {
3227 return;
3228 }
3229
3230 $time = date("Y-m-d H:i:s", time());
3231
3232 $hier_ids = array();
3233 $skip = array();
3234 foreach($a_hids as $a_hid)
3235 {
3236 if ($a_hid == "")
3237 {
3238 continue;
3239 }
3240 $a_hid = explode(":", $a_hid);
3241
3242 // check, whether new hid is child of existing one or vice versa
3243 reset($hier_ids);
3244 foreach($hier_ids as $h)
3245 {
3246 if($h."_" == substr($a_hid[0], 0, strlen($h) + 1))
3247 {
3248 $skip[] = $a_hid[0];
3249 }
3250 if($a_hid[0]."_" == substr($h, 0, strlen($a_hid[0]) + 1))
3251 {
3252 $skip[] = $h;
3253 }
3254 }
3255 $pc_id[$a_hid[0]] = $a_hid[1];
3256 if ($a_hid[0] != "")
3257 {
3258 $hier_ids[$a_hid[0]] = $a_hid[0];
3259 }
3260 }
3261 foreach ($skip as $s)
3262 {
3263 unset($hier_ids[$s]);
3264 }
3265 include_once("./Services/COPage/classes/class.ilPageContent.php");
3266 $hier_ids = ilPageContent::sortHierIds($hier_ids);
3267 $nr = 1;
3268 foreach($hier_ids as $hid)
3269 {
3270 $curr_node = $this->getContentNode($hid, $pc_id[$hid]);
3271 if (is_object($curr_node))
3272 {
3273 if ($curr_node->node_name() == "PageContent")
3274 {
3275 $content = $this->dom->dump_node($curr_node);
3276 // remove pc and hier ids
3277 $content = preg_replace('/PCID=\"[a-z0-9]*\"/i',"",$content);
3278 $content = preg_replace('/HierId=\"[a-z0-9_]*\"/i',"",$content);
3279
3280 $ilUser->addToPCClipboard($content, $time, $nr);
3281 $nr++;
3282 }
3283 }
3284 }
3285 include_once("./Modules/LearningModule/classes/class.ilEditClipboard.php");
3287 }
3288
3292 function pasteContents($a_hier_id, $a_self_ass = false)
3293 {
3294 global $ilUser;
3295
3296 $a_hid = explode(":", $a_hier_id);
3297 $content = $ilUser->getPCClipboardContent();
3298
3299 // we insert from last to first, because we insert all at the
3300 // same hier_id
3301 for ($i = count($content) - 1; $i >= 0; $i--)
3302 {
3303
3304 $c = $content[$i];
3305 $temp_dom = domxml_open_mem('<?xml version="1.0" encoding="UTF-8"?>'.$c,
3306 DOMXML_LOAD_PARSING, $error);
3307 if(empty($error))
3308 {
3309 $this->handleCopiedContent($temp_dom, $a_self_ass);
3310 $xpc = xpath_new_context($temp_dom);
3311 $path = "//PageContent";
3312 $res = xpath_eval($xpc, $path);
3313 if (count($res->nodeset) > 0)
3314 {
3315 $new_pc_node = $res->nodeset[0];
3316 $cloned_pc_node = $new_pc_node->clone_node (true);
3317 $cloned_pc_node->unlink_node ($cloned_pc_node);
3318 $this->insertContentNode ($cloned_pc_node, $a_hid[0],
3319 IL_INSERT_AFTER, $a_hid[1]);
3320 }
3321 }
3322 else
3323 {
3324//var_dump($error);
3325 }
3326 }
3327 $e = $this->update();
3328//var_dump($e);
3329 }
3330
3334 function switchEnableMultiple($a_hids, $a_update = true, $a_self_ass = false)
3335 {
3336 if (!is_array($a_hids))
3337 {
3338 return;
3339 }
3340 $obj = & $this->content_obj;
3341
3342 foreach($a_hids as $a_hid)
3343 {
3344 $a_hid = explode(":", $a_hid);
3345 $curr_node = $this->getContentNode($a_hid[0], $a_hid[1]);
3346 if (is_object($curr_node))
3347 {
3348 if ($curr_node->node_name() == "PageContent")
3349 {
3350 $cont_obj = $this->getContentObject($a_hid[0], $a_hid[1]);
3351 if ($cont_obj->isEnabled ())
3352 {
3353 // do not deactivate question nodes in assessment pages
3354 if (!$this->checkForTag("Question", $a_hid[0], $a_hid[1]) || $a_self_ass)
3355 {
3356 $cont_obj->disable();
3357 }
3358 }
3359 else
3360 {
3361 $cont_obj->enable();
3362 }
3363 }
3364 }
3365 }
3366
3367 if ($a_update)
3368 {
3369 return $this->update();
3370 }
3371 }
3372
3373
3381 function deleteContentFromHierId($a_hid, $a_update = true)
3382 {
3383 $hier_ids = $this->getHierIds();
3384
3385 // iterate all hierarchical ids
3386 foreach ($hier_ids as $hier_id)
3387 {
3388 // delete top level nodes only
3389 if (!is_int(strpos($hier_id, "_")))
3390 {
3391 if ($hier_id != "pg" && $hier_id >= $a_hid)
3392 {
3393 $curr_node = $this->getContentNode($hier_id);
3394 $curr_node->unlink_node($curr_node);
3395 }
3396 }
3397 }
3398 if ($a_update)
3399 {
3400 return $this->update();
3401 }
3402 }
3403
3411 function deleteContentBeforeHierId($a_hid, $a_update = true)
3412 {
3413 $hier_ids = $this->getHierIds();
3414
3415 // iterate all hierarchical ids
3416 foreach ($hier_ids as $hier_id)
3417 {
3418 // delete top level nodes only
3419 if (!is_int(strpos($hier_id, "_")))
3420 {
3421 if ($hier_id != "pg" && $hier_id < $a_hid)
3422 {
3423 $curr_node = $this->getContentNode($hier_id);
3424 $curr_node->unlink_node($curr_node);
3425 }
3426 }
3427 }
3428 if ($a_update)
3429 {
3430 return $this->update();
3431 }
3432 }
3433
3434
3442 static function _moveContentAfterHierId(&$a_source_page, &$a_target_page, $a_hid)
3443 {
3444 $hier_ids = $a_source_page->getHierIds();
3445
3446 $copy_ids = array();
3447
3448 // iterate all hierarchical ids
3449 foreach ($hier_ids as $hier_id)
3450 {
3451 // move top level nodes only
3452 if (!is_int(strpos($hier_id, "_")))
3453 {
3454 if ($hier_id != "pg" && $hier_id >= $a_hid)
3455 {
3456 $copy_ids[] = $hier_id;
3457 }
3458 }
3459 }
3460 asort($copy_ids);
3461
3462 $parent_node = $a_target_page->getContentNode("pg");
3463 $target_dom = $a_target_page->getDom();
3464 $parent_childs = $parent_node->child_nodes();
3465 $cnt_parent_childs = count($parent_childs);
3466//echo "-$cnt_parent_childs-";
3467 $first_child = $parent_childs[0];
3468 foreach($copy_ids as $copy_id)
3469 {
3470 $source_node = $a_source_page->getContentNode($copy_id);
3471
3472 $new_node = $source_node->clone_node(true);
3473 $new_node->unlink_node($new_node);
3474
3475 $source_node->unlink_node($source_node);
3476
3477 if($cnt_parent_childs == 0)
3478 {
3479 $new_node = $parent_node->append_child($new_node);
3480 }
3481 else
3482 {
3483 //$target_dom->import_node($new_node);
3484 $new_node = $first_child->insert_before($new_node, $first_child);
3485 }
3486 $parent_childs = $parent_node->child_nodes();
3487
3488 //$cnt_parent_childs++;
3489 }
3490
3491 $a_target_page->update();
3492 $a_source_page->update();
3493
3494 }
3495
3499 function insertContent(&$a_cont_obj, $a_pos, $a_mode = IL_INSERT_AFTER, $a_pcid = "")
3500 {
3501//echo "-".$a_pos."-".$a_pcid."-";
3502 // move mode into container elements is always INSERT_CHILD
3503 $curr_node = $this->getContentNode($a_pos, $a_pcid);
3504 $curr_name = $curr_node->node_name();
3505
3506 // @todo: try to generalize this
3507 if (($curr_name == "TableData") || ($curr_name == "PageObject") ||
3508 ($curr_name == "ListItem") || ($curr_name == "Section")
3509 || ($curr_name == "Tab") || ($curr_name == "ContentPopup"))
3510 {
3511 $a_mode = IL_INSERT_CHILD;
3512 }
3513
3514 $hid = $curr_node->get_attribute("HierId");
3515 if ($hid != "")
3516 {
3517//echo "-".$a_pos."-".$hid."-";
3518 $a_pos = $hid;
3519 }
3520
3521 if($a_mode != IL_INSERT_CHILD) // determine parent hierarchical id
3522 { // of sibling at $a_pos
3523 $pos = explode("_", $a_pos);
3524 $target_pos = array_pop($pos);
3525 $parent_pos = implode($pos, "_");
3526 }
3527 else // if we should insert a child, $a_pos is alreade the hierarchical id
3528 { // of the parent node
3529 $parent_pos = $a_pos;
3530 }
3531
3532 // get the parent node
3533 if($parent_pos != "")
3534 {
3535 $parent_node = $this->getContentNode($parent_pos);
3536 }
3537 else
3538 {
3539 $parent_node = $this->getNode();
3540 }
3541
3542 // count the parent children
3543 $parent_childs = $parent_node->child_nodes();
3544 $cnt_parent_childs = count($parent_childs);
3545//echo "ZZ$a_mode";
3546 switch ($a_mode)
3547 {
3548 // insert new node after sibling at $a_pos
3549 case IL_INSERT_AFTER:
3550 $new_node = $a_cont_obj->getNode();
3551 //$a_pos = ilPageContent::incEdId($a_pos);
3552 //$curr_node = $this->getContentNode($a_pos);
3553//echo "behind $a_pos:";
3554 if($succ_node = $curr_node->next_sibling())
3555 {
3556 $new_node = $succ_node->insert_before($new_node, $succ_node);
3557 }
3558 else
3559 {
3560//echo "movin doin append_child";
3561 $new_node = $parent_node->append_child($new_node);
3562 }
3563 $a_cont_obj->setNode($new_node);
3564 break;
3565
3566 case IL_INSERT_BEFORE:
3567//echo "INSERT_BEF";
3568 $new_node = $a_cont_obj->getNode();
3569 $succ_node = $this->getContentNode($a_pos);
3570 $new_node = $succ_node->insert_before($new_node, $succ_node);
3571 $a_cont_obj->setNode($new_node);
3572 break;
3573
3574 // insert new node as first child of parent $a_pos (= $a_parent)
3575 case IL_INSERT_CHILD:
3576//echo "insert as child:parent_childs:$cnt_parent_childs:<br>";
3577 $new_node = $a_cont_obj->getNode();
3578 if($cnt_parent_childs == 0)
3579 {
3580 $new_node = $parent_node->append_child($new_node);
3581 }
3582 else
3583 {
3584 $new_node = $parent_childs[0]->insert_before($new_node, $parent_childs[0]);
3585 }
3586 $a_cont_obj->setNode($new_node);
3587//echo "PP";
3588 break;
3589 }
3590
3591 //check for PlaceHolder to remove in EditMode-keep in Layout Mode
3592 if (!$this->getPageConfig()->getEnablePCType("PlaceHolder")) {
3593 $sub_nodes = $curr_node->child_nodes() ;
3594 foreach ( $sub_nodes as $sub_node ) {
3595 if ($sub_node->node_name() == "PlaceHolder") {
3596 $curr_node->unlink_node();
3597 }
3598 }
3599 }
3600 }
3601
3605 function insertContentNode(&$a_cont_node, $a_pos, $a_mode = IL_INSERT_AFTER, $a_pcid = "")
3606 {
3607 // move mode into container elements is always INSERT_CHILD
3608 $curr_node = $this->getContentNode($a_pos, $a_pcid);
3609 $curr_name = $curr_node->node_name();
3610
3611 // @todo: try to generalize
3612 if (($curr_name == "TableData") || ($curr_name == "PageObject") ||
3613 ($curr_name == "ListItem") || ($curr_name == "Section")
3614 || ($curr_name == "Tab") || ($curr_name == "ContentPopup"))
3615 {
3616 $a_mode = IL_INSERT_CHILD;
3617 }
3618
3619 $hid = $curr_node->get_attribute("HierId");
3620 if ($hid != "")
3621 {
3622 $a_pos = $hid;
3623 }
3624
3625 if($a_mode != IL_INSERT_CHILD) // determine parent hierarchical id
3626 { // of sibling at $a_pos
3627 $pos = explode("_", $a_pos);
3628 $target_pos = array_pop($pos);
3629 $parent_pos = implode($pos, "_");
3630 }
3631 else // if we should insert a child, $a_pos is alreade the hierarchical id
3632 { // of the parent node
3633 $parent_pos = $a_pos;
3634 }
3635
3636 // get the parent node
3637 if($parent_pos != "")
3638 {
3639 $parent_node = $this->getContentNode($parent_pos);
3640 }
3641 else
3642 {
3643 $parent_node = $this->getNode();
3644 }
3645
3646 // count the parent children
3647 $parent_childs = $parent_node->child_nodes();
3648 $cnt_parent_childs = count($parent_childs);
3649
3650 switch ($a_mode)
3651 {
3652 // insert new node after sibling at $a_pos
3653 case IL_INSERT_AFTER:
3654 //$new_node = $a_cont_obj->getNode();
3655 if($succ_node = $curr_node->next_sibling())
3656 {
3657 $a_cont_node = $succ_node->insert_before($a_cont_node, $succ_node);
3658 }
3659 else
3660 {
3661 $a_cont_node = $parent_node->append_child($a_cont_node);
3662 }
3663 //$a_cont_obj->setNode($new_node);
3664 break;
3665
3666 case IL_INSERT_BEFORE:
3667 //$new_node = $a_cont_obj->getNode();
3668 $succ_node = $this->getContentNode($a_pos);
3669 $a_cont_node = $succ_node->insert_before($a_cont_node, $succ_node);
3670 //$a_cont_obj->setNode($new_node);
3671 break;
3672
3673 // insert new node as first child of parent $a_pos (= $a_parent)
3674 case IL_INSERT_CHILD:
3675 //$new_node = $a_cont_obj->getNode();
3676 if($cnt_parent_childs == 0)
3677 {
3678 $a_cont_node = $parent_node->append_child($a_cont_node);
3679 }
3680 else
3681 {
3682 $a_cont_node = $parent_childs[0]->insert_before($a_cont_node, $parent_childs[0]);
3683 }
3684 //$a_cont_obj->setNode($new_node);
3685 break;
3686 }
3687 }
3688
3693 function moveContentBefore($a_source, $a_target, $a_spcid = "", $a_tpcid = "")
3694 {
3695 if($a_source == $a_target)
3696 {
3697 return;
3698 }
3699
3700 // clone the node
3701 $content = $this->getContentObject($a_source, $a_spcid);
3702 $source_node = $content->getNode();
3703 $clone_node = $source_node->clone_node(true);
3704
3705 // delete source node
3706 $this->deleteContent($a_source, false, $a_spcid);
3707
3708 // insert cloned node at target
3709 $content->setNode($clone_node);
3710 $this->insertContent($content, $a_target, IL_INSERT_BEFORE, $a_tpcid);
3711 return $this->update();
3712
3713 }
3714
3719 function moveContentAfter($a_source, $a_target, $a_spcid = "", $a_tpcid = "")
3720 {
3721 if($a_source == $a_target)
3722 {
3723 return;
3724 }
3725
3726 // clone the node
3727 $content = $this->getContentObject($a_source, $a_spcid);
3728 $source_node = $content->getNode();
3729 $clone_node = $source_node->clone_node(true);
3730
3731 // delete source node
3732 $this->deleteContent($a_source, false, $a_spcid);
3733
3734 // insert cloned node at target
3735 $content->setNode($clone_node);
3736 $this->insertContent($content, $a_target, IL_INSERT_AFTER, $a_tpcid);
3737 return $this->update();
3738 }
3739
3743 // @todo: move to paragraph
3745 {
3746 $a_content = preg_replace('/\[com\]/i',"<Comment>",$a_content);
3747 $a_content = preg_replace('/\[\/com\]/i',"</Comment>",$a_content);
3748 $a_content = preg_replace('/\[emp]/i',"<Emph>",$a_content);
3749 $a_content = preg_replace('/\[\/emp\]/i',"</Emph>",$a_content);
3750 $a_content = preg_replace('/\[str]/i',"<Strong>",$a_content);
3751 $a_content = preg_replace('/\[\/str\]/i',"</Strong>",$a_content);
3752 }
3753
3758 function insertInstIntoIDs($a_inst, $a_res_ref_to_obj_id = true)
3759 {
3760 // insert inst id into internal links
3761 $xpc = xpath_new_context($this->dom);
3762 $path = "//IntLink";
3763 $res = xpath_eval($xpc, $path);
3764 for($i = 0; $i < count($res->nodeset); $i++)
3765 {
3766 $target = $res->nodeset[$i]->get_attribute("Target");
3767 $type = $res->nodeset[$i]->get_attribute("Type");
3768
3769 if (substr($target, 0, 4) == "il__")
3770 {
3771 $id = substr($target, 4, strlen($target) - 4);
3772
3773 // convert repository links obj_<ref_id> to <type>_<obj_id>
3774 // this leads to bug 6685.
3775 if ($a_res_ref_to_obj_id && $type == "RepositoryItem")
3776 {
3777 $id_arr = explode("_", $id);
3778
3779 // changed due to bug 6685
3780 $ref_id = $id_arr[1];
3781 $obj_id = ilObject::_lookupObjId($id_arr[1]);
3782
3783 $otype = ilObject::_lookupType($obj_id);
3784 if ($obj_id > 0)
3785 {
3786 // changed due to bug 6685
3787 // the ref_id should be used, if the content is
3788 // imported on the same installation
3789 // the obj_id should be used, if a different
3790 // installation imports, but has an import_id for
3791 // the object id.
3792 $id = $otype."_".$obj_id."_".$ref_id;
3793 //$id = $otype."_".$ref_id;
3794 }
3795 }
3796 $new_target = "il_".$a_inst."_".$id;
3797 $res->nodeset[$i]->set_attribute("Target", $new_target);
3798 }
3799 }
3800 unset($xpc);
3801
3802 // @todo: move to media/fileitems/questions, ...
3803
3804 // insert inst id into media aliases
3805 $xpc = xpath_new_context($this->dom);
3806 $path = "//MediaAlias";
3807 $res = xpath_eval($xpc, $path);
3808 for($i = 0; $i < count($res->nodeset); $i++)
3809 {
3810 $origin_id = $res->nodeset[$i]->get_attribute("OriginId");
3811 if (substr($origin_id, 0, 4) == "il__")
3812 {
3813 $new_id = "il_".$a_inst."_".substr($origin_id, 4, strlen($origin_id) - 4);
3814 $res->nodeset[$i]->set_attribute("OriginId", $new_id);
3815 }
3816 }
3817 unset($xpc);
3818
3819 // insert inst id file item identifier entries
3820 $xpc = xpath_new_context($this->dom);
3821 $path = "//FileItem/Identifier";
3822 $res = xpath_eval($xpc, $path);
3823 for($i = 0; $i < count($res->nodeset); $i++)
3824 {
3825 $origin_id = $res->nodeset[$i]->get_attribute("Entry");
3826 if (substr($origin_id, 0, 4) == "il__")
3827 {
3828 $new_id = "il_".$a_inst."_".substr($origin_id, 4, strlen($origin_id) - 4);
3829 $res->nodeset[$i]->set_attribute("Entry", $new_id);
3830 }
3831 }
3832 unset($xpc);
3833
3834 // insert inst id into question references
3835 $xpc = xpath_new_context($this->dom);
3836 $path = "//Question";
3837 $res = xpath_eval($xpc, $path);
3838 for($i = 0; $i < count($res->nodeset); $i++)
3839 {
3840 $qref = $res->nodeset[$i]->get_attribute("QRef");
3841//echo "<br>setted:".$qref;
3842 if (substr($qref, 0, 4) == "il__")
3843 {
3844 $new_id = "il_".$a_inst."_".substr($qref, 4, strlen($qref) - 4);
3845//echo "<br>setting:".$new_id;
3846 $res->nodeset[$i]->set_attribute("QRef", $new_id);
3847 }
3848 }
3849 unset($xpc);
3850
3851 // insert inst id into content snippets
3852 $xpc = xpath_new_context($this->dom);
3853 $path = "//ContentInclude";
3854 $res = xpath_eval($xpc, $path);
3855 for($i = 0; $i < count($res->nodeset); $i++)
3856 {
3857 $ci = $res->nodeset[$i]->get_attribute("InstId");
3858 if ($ci == "")
3859 {
3860 $res->nodeset[$i]->set_attribute("InstId", $a_inst);
3861 }
3862 }
3863 unset($xpc);
3864
3865 }
3866
3870 function checkPCIds()
3871 {
3872 $this->builddom();
3873 $mydom = $this->dom;
3874
3875 $sep = $path = "";
3876 foreach ($this->id_elements as $el)
3877 {
3878 $path.= $sep."//".$el."[not(@PCID)]";
3879 $sep = " | ";
3880 $path.= $sep."//".$el."[@PCID='']";
3881 }
3882
3883 $xpc = xpath_new_context($mydom);
3884 $res = & xpath_eval($xpc, $path);
3885
3886 if (count ($res->nodeset) > 0)
3887 {
3888 return false;
3889 }
3890 return true;
3891 }
3892
3899 function getAllPCIds()
3900 {
3901 $this->builddom();
3902 $mydom = $this->dom;
3903
3904 $pcids = array();
3905
3906 $sep = $path = "";
3907 foreach ($this->id_elements as $el)
3908 {
3909 $path.= $sep."//".$el."[@PCID]";
3910 $sep = " | ";
3911 }
3912
3913 // get existing ids
3914 $xpc = xpath_new_context($mydom);
3915 $res = & xpath_eval($xpc, $path);
3916
3917 for ($i = 0; $i < count ($res->nodeset); $i++)
3918 {
3919 $node = $res->nodeset[$i];
3920 $pcids[] = $node->get_attribute("PCID");
3921 }
3922 return $pcids;
3923 }
3924
3931 function existsPCId($a_pc_id)
3932 {
3933 $this->builddom();
3934 $mydom = $this->dom;
3935
3936 $pcids = array();
3937
3938 $sep = $path = "";
3939 foreach ($this->id_elements as $el)
3940 {
3941 $path.= $sep."//".$el."[@PCID='".$a_pc_id."']";
3942 $sep = " | ";
3943 }
3944
3945 // get existing ids
3946 $xpc = xpath_new_context($mydom);
3947 $res = & xpath_eval($xpc, $path);
3948 return (count($res->nodeset) > 0);
3949 }
3950
3957 function generatePcId($a_pc_ids = false)
3958 {
3959 if ($a_pc_ids === false)
3960 {
3961 $a_pc_ids = $this->getAllPCIds();
3962 }
3963 $id = ilUtil::randomHash(10, $a_pc_ids);
3964 return $id;
3965 }
3966
3967
3971 function insertPCIds()
3972 {
3973 $this->builddom();
3974 $mydom = $this->dom;
3975
3976 $pcids = $this->getAllPCIds();
3977
3978 // add missing ones
3979 $sep = $path = "";
3980 foreach ($this->id_elements as $el)
3981 {
3982 $path.= $sep."//".$el."[not(@PCID)]";
3983 $sep = " | ";
3984 $path.= $sep."//".$el."[@PCID='']";
3985 $sep = " | ";
3986 }
3987 $xpc = xpath_new_context($mydom);
3988 $res = & xpath_eval($xpc, $path);
3989
3990 for ($i = 0; $i < count ($res->nodeset); $i++)
3991 {
3992 $node = $res->nodeset[$i];
3993 $id = ilUtil::randomHash(10, $pcids);
3994 $pcids[] = $id;
3995//echo "setting-".$id."-";
3996 $res->nodeset[$i]->set_attribute("PCID", $id);
3997 }
3998 }
3999
4004 {
4005 $this->builddom();
4006 $this->addHierIds();
4007 $mydom = $this->dom;
4008
4009 // get existing ids
4010 $path = "//PageContent";
4011 $xpc = xpath_new_context($mydom);
4012 $res = & xpath_eval($xpc, $path);
4013
4014 $hashes = array();
4015 require_once("./Services/COPage/classes/class.ilPCParagraph.php");
4016 for ($i = 0; $i < count ($res->nodeset); $i++)
4017 {
4018 $hier_id = $res->nodeset[$i]->get_attribute("HierId");
4019 $pc_id = $res->nodeset[$i]->get_attribute("PCID");
4020 $dump = $mydom->dump_node($res->nodeset[$i]);
4021 if (($hpos = strpos($dump, ' HierId="'.$hier_id.'"')) > 0)
4022 {
4023 $dump = substr($dump, 0, $hpos).
4024 substr($dump, $hpos + strlen(' HierId="'.$hier_id.'"'));
4025 }
4026
4027 $childs = $res->nodeset[$i]->child_nodes();
4028 $content = "";
4029 if ($childs[0] && $childs[0]->node_name() == "Paragraph")
4030 {
4031 $content = $mydom->dump_node($childs[0]);
4032 $content = substr($content, strpos($content, ">") + 1,
4033 strrpos($content, "<") - (strpos($content, ">") + 1));
4034//var_dump($content);
4035 $content = ilPCParagraph::xml2output($content);
4036//var_dump($content);
4037 }
4038 //$hashes[$hier_id] =
4039 // array("PCID" => $pc_id, "hash" => md5($dump));
4040 $hashes[$pc_id] =
4041 array("hier_id" => $hier_id, "hash" => md5($dump), "content" => $content);
4042 }
4043
4044 return $hashes;
4045 }
4046
4050// @todo: move to questions
4052 {
4053 $this->builddom();
4054 $mydom = $this->dom;
4055
4056 // Get question IDs
4057 $path = "//Question";
4058 $xpc = xpath_new_context($mydom);
4059 $res = & xpath_eval($xpc, $path);
4060
4061 $q_ids = array();
4062 include_once("./Services/Link/classes/class.ilInternalLink.php");
4063 for ($i = 0; $i < count ($res->nodeset); $i++)
4064 {
4065 $qref = $res->nodeset[$i]->get_attribute("QRef");
4066
4067 $inst_id = ilInternalLink::_extractInstOfTarget($qref);
4069
4070 if (!($inst_id > 0))
4071 {
4072 if ($obj_id > 0)
4073 {
4074 $q_ids[] = $obj_id;
4075 }
4076 }
4077 }
4078 return $q_ids;
4079 }
4080
4081// @todo: move to paragraph
4082 function send_paragraph ($par_id, $filename)
4083 {
4084 $this->builddom();
4085
4086 $mydom = $this->dom;
4087
4088 $xpc = xpath_new_context($mydom);
4089
4090 //$path = "//PageContent[position () = $par_id]/Paragraph";
4091 //$path = "//Paragraph[$par_id]";
4092 $path = "/descendant::Paragraph[position() = $par_id]";
4093
4094 $res = & xpath_eval($xpc, $path);
4095
4096 if (count ($res->nodeset) != 1)
4097 die ("Should not happen");
4098
4099 $context_node = $res->nodeset[0];
4100
4101 // get plain text
4102
4103 $childs = $context_node->child_nodes();
4104
4105 for($j=0; $j<count($childs); $j++)
4106 {
4107 $content .= $mydom->dump_node($childs[$j]);
4108 }
4109
4110 $content = str_replace("<br />", "\n", $content);
4111 $content = str_replace("<br/>", "\n", $content);
4112
4113 $plain_content = html_entity_decode($content);
4114
4115 ilUtil::deliverData($plain_content, $filename);
4116 /*
4117 $file_type = "application/octet-stream";
4118 header("Content-type: ".$file_type);
4119 header("Content-disposition: attachment; filename=\"$filename\"");
4120 echo $plain_content;*/
4121 exit();
4122 }
4123
4127// @todo: deprecated?
4128 function getFO()
4129 {
4130 $xml = $this->getXMLFromDom(false, true, true);
4131 $xsl = file_get_contents("./Services/COPage/xsl/page_fo.xsl");
4132 $args = array( '/_xml' => $xml, '/_xsl' => $xsl );
4133 $xh = xslt_create();
4134
4135 $params = array ();
4136
4137
4138 $fo = xslt_process($xh,"arg:/_xml","arg:/_xsl",NULL,$args, $params);
4139 var_dump($fo);
4140 // do some replacements
4141 $fo = str_replace("\n", "", $fo);
4142 $fo = str_replace("<br/>", "<br>", $fo);
4143 $fo = str_replace("<br>", "\n", $fo);
4144
4145 xslt_free($xh);
4146
4147 //
4148 $fo = substr($fo, strpos($fo,">") + 1);
4149//echo "<br><b>fo:</b><br>".htmlentities($fo); flush();
4150 return $fo;
4151 }
4152
4153 function registerOfflineHandler ($handler) {
4154 $this->offline_handler = $handler;
4155 }
4156
4164 {
4166 }
4167
4168
4172 static function _lookupContainsDeactivatedElements($a_id, $a_parent_type, $a_lang = "-")
4173 {
4174 global $ilDB;
4175
4176 if ($a_lang == "")
4177 {
4178 $a_lang = "-";
4179 }
4180
4181 $query = "SELECT * FROM page_object WHERE page_id = ".
4182 $ilDB->quote($a_id, "integer")." AND ".
4183 " parent_type = ".$ilDB->quote($a_parent_type, "text")." AND ".
4184 " lang = ".$ilDB->quote($a_lang, "text")." AND ".
4185 " inactive_elements = ".$ilDB->quote(1, "integer");
4186 $obj_set = $ilDB->query($query);
4187
4188 if ($obj_rec = $obj_set->fetchRow(ilDBConstants::FETCHMODE_ASSOC))
4189 {
4190 return true;
4191 }
4192
4193 return false;
4194 }
4195
4203 {
4204 if (strpos($a_content, " Enabled=\"False\""))
4205 {
4206 return true;
4207 }
4208 return false;
4209 }
4210
4215 {
4216 global $ilDB;
4217
4218 $h_query = "SELECT * FROM page_history ".
4219 " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
4220 " AND parent_type = ".$ilDB->quote($this->getParentType(), "text").
4221 " AND lang = ".$ilDB->quote($this->getLanguage(), "text").
4222 " ORDER BY hdate DESC";
4223
4224 $hset = $ilDB->query($h_query);
4225 $hentries = array();
4226
4227 while ($hrec = $ilDB->fetchAssoc($hset))
4228 {
4229 $hrec["sortkey"] = (int) $hrec["nr"];
4230 $hrec["user"] = (int) $hrec["user_id"];
4231 $hentries[] = $hrec;
4232 }
4233//var_dump($hentries);
4234 return $hentries;
4235 }
4236
4240 function getHistoryEntry($a_old_nr)
4241 {
4242 global $ilDB;
4243
4244 $res = $ilDB->queryF("SELECT * FROM page_history ".
4245 " WHERE page_id = %s ".
4246 " AND parent_type = %s ".
4247 " AND nr = %s".
4248 " AND lang = %s",
4249 array("integer", "text", "integer", "text"),
4250 array($this->getId(), $this->getParentType(), $a_old_nr, $this->getLanguage()));
4251 if ($hrec = $ilDB->fetchAssoc($res))
4252 {
4253 return $hrec;
4254 }
4255
4256 return false;
4257 }
4258
4259
4266 function getHistoryInfo($a_nr)
4267 {
4268 global $ilDB;
4269
4270 // determine previous entry
4271 $and_nr = ($a_nr > 0)
4272 ? " AND nr < ".$ilDB->quote((int) $a_nr, "integer")
4273 : "";
4274 $res = $ilDB->query("SELECT MAX(nr) mnr FROM page_history ".
4275 " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
4276 " AND parent_type = ".$ilDB->quote($this->getParentType(), "text").
4277 " AND lang = ".$ilDB->quote($this->getLanguage(), "text").
4278 $and_nr);
4279 $row = $ilDB->fetchAssoc($res);
4280 if ($row["mnr"] > 0)
4281 {
4282 $res = $ilDB->query("SELECT * FROM page_history ".
4283 " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
4284 " AND parent_type = ".$ilDB->quote($this->getParentType(), "text").
4285 " AND lang = ".$ilDB->quote($this->getLanguage(), "text").
4286 " AND nr = ".$ilDB->quote((int) $row["mnr"], "integer"));
4287 $row = $ilDB->fetchAssoc($res);
4288 $ret["previous"] = $row;
4289 }
4290
4291 // determine next entry
4292 $res = $ilDB->query("SELECT MIN(nr) mnr FROM page_history ".
4293 " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
4294 " AND parent_type = ".$ilDB->quote($this->getParentType(), "text").
4295 " AND lang = ".$ilDB->quote($this->getLanguage(), "text").
4296 " AND nr > ".$ilDB->quote((int) $a_nr, "integer"));
4297 $row = $ilDB->fetchAssoc($res);
4298 if ($row["mnr"] > 0)
4299 {
4300 $res = $ilDB->query("SELECT * FROM page_history ".
4301 " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
4302 " AND parent_type = ".$ilDB->quote($this->getParentType(), "text").
4303 " AND lang = ".$ilDB->quote($this->getLanguage(), "text").
4304 " AND nr = ".$ilDB->quote((int) $row["mnr"], "integer"));
4305 $row = $ilDB->fetchAssoc($res);
4306 $ret["next"] = $row;
4307 }
4308
4309 // current
4310 if ($a_nr > 0)
4311 {
4312 $res = $ilDB->query("SELECT * FROM page_history ".
4313 " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
4314 " AND parent_type = ".$ilDB->quote($this->getParentType(), "text").
4315 " AND lang = ".$ilDB->quote($this->getLanguage(), "text").
4316 " AND nr = ".$ilDB->quote((int) $a_nr, "integer"));
4317 $row = $ilDB->fetchAssoc($res);
4318 }
4319 else
4320 {
4321 $res = $ilDB->query("SELECT page_id, last_change hdate, parent_type, parent_id, last_change_user user_id, content, lang FROM page_object ".
4322 " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
4323 " AND parent_type = ".$ilDB->quote($this->getParentType(), "text").
4324 " AND lang = ".$ilDB->quote($this->getLanguage(), "text"));
4325 $row = $ilDB->fetchAssoc($res);
4326 }
4327 $ret["current"] = $row;
4328
4329 return $ret;
4330 }
4331
4332 function addChangeDivClasses($a_hashes)
4333 {
4334 $xpc = xpath_new_context($this->dom);
4335 $path = "/*[1]";
4336 $res = xpath_eval($xpc, $path);
4337 $rnode = $res->nodeset[0];
4338
4339//echo "A";
4340 foreach($a_hashes as $pc_id => $h)
4341 {
4342//echo "B";
4343 if ($h["change"] != "")
4344 {
4345 $dc_node = $this->dom->create_element("DivClass");
4346 $dc_node->set_attribute("HierId", $h["hier_id"]);
4347 $dc_node->set_attribute("Class", "ilEdit".$h["change"]);
4348 $dc_node = $rnode->append_child($dc_node);
4349 }
4350 }
4351//echo "<br><br><br><br><br><br>".htmlentities($this->getXMLFromDom());
4352 }
4353
4360 function compareVersion($a_left, $a_right)
4361 {
4362 // get page objects
4363 include_once("./Services/COPage/classes/class.ilPageObjectFactory.php");
4364 $l_page = ilPageObjectFactory::getInstance($this->getParentType(), $this->getId(), $a_left);
4365 $r_page = ilPageObjectFactory::getInstance($this->getParentType(), $this->getId(), $a_right);
4366
4367 $l_hashes = $l_page->getPageContentsHashes();
4368 $r_hashes = $r_page->getPageContentsHashes();
4369 // determine all deleted and changed page elements
4370 foreach ($l_hashes as $pc_id => $h)
4371 {
4372 if (!isset($r_hashes[$pc_id]))
4373 {
4374 $l_hashes[$pc_id]["change"] = "Deleted";
4375 }
4376 else
4377 {
4378 if ($l_hashes[$pc_id]["hash"] != $r_hashes[$pc_id]["hash"])
4379 {
4380 $l_hashes[$pc_id]["change"] = "Modified";
4381 $r_hashes[$pc_id]["change"] = "Modified";
4382
4383 include_once("./Services/COPage/mediawikidiff/class.WordLevelDiff.php");
4384 // if modified element is a paragraph, highlight changes
4385 if ($l_hashes[$pc_id]["content"] != "" &&
4386 $r_hashes[$pc_id]["content"] != "")
4387 {
4388 $new_left = str_replace("\n", "<br />", $l_hashes[$pc_id]["content"]);
4389 $new_right = str_replace("\n", "<br />", $r_hashes[$pc_id]["content"]);
4390 $wldiff = new WordLevelDiff(array($new_left),
4391 array($new_right));
4392 $new_left = $wldiff->orig();
4393 $new_right = $wldiff->closing();
4394 $l_page->setParagraphContent($l_hashes[$pc_id]["hier_id"], $new_left[0]);
4395 $r_page->setParagraphContent($l_hashes[$pc_id]["hier_id"], $new_right[0]);
4396 }
4397 }
4398 }
4399 }
4400
4401 // determine all new paragraphs
4402 foreach ($r_hashes as $pc_id => $h)
4403 {
4404 if (!isset($l_hashes[$pc_id]))
4405 {
4406 $r_hashes[$pc_id]["change"] = "New";
4407 }
4408 }
4409 $l_page->addChangeDivClasses($l_hashes);
4410 $r_page->addChangeDivClasses($r_hashes);
4411
4412 return array("l_page" => $l_page, "r_page" => $r_page,
4413 "l_changes" => $l_hashes, "r_changes" => $r_hashes);
4414 }
4415
4420 {
4421 global $ilDB;
4422
4423 $ilDB->manipulate("UPDATE page_object ".
4424 " SET view_cnt = view_cnt + 1 ".
4425 " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
4426 " AND parent_type = ".$ilDB->quote($this->getParentType(), "text").
4427 " AND lang = ".$ilDB->quote($this->getLanguage(), "text"));
4428 }
4429
4437 static function getRecentChanges($a_parent_type, $a_parent_id, $a_period = 30, $a_lang = "")
4438 {
4439 global $ilDB;
4440
4441 $and_lang = "";
4442 if ($a_lang != "")
4443 {
4444 $and_lang = " AND lang = ".$ilDB->quote($a_lang, "text");
4445 }
4446
4447 $page_changes = array();
4448 $limit_ts = date('Y-m-d H:i:s', time() - ($a_period * 24 * 60 * 60));
4449 $q = "SELECT * FROM page_object ".
4450 " WHERE parent_id = ".$ilDB->quote($a_parent_id, "integer").
4451 " AND parent_type = ".$ilDB->quote($a_parent_type, "text").
4452 " AND last_change >= ".$ilDB->quote($limit_ts, "timestamp").$and_lang;
4453 // " AND (TO_DAYS(now()) - TO_DAYS(last_change)) <= ".((int)$a_period);
4454 $set = $ilDB->query($q);
4455 while($page = $ilDB->fetchAssoc($set))
4456 {
4457 $page_changes[] = array(
4458 "date" => $page["last_change"],
4459 "id" => $page["page_id"],
4460 "lang" => $page["lang"],
4461 "type" => "page",
4462 "user" => $page["last_change_user"]);
4463 }
4464
4465 $and_str = "";
4466 if ($a_period > 0)
4467 {
4468 $limit_ts = date('Y-m-d H:i:s', time() - ($a_period * 24 * 60 * 60));
4469 $and_str = " AND hdate >= ".$ilDB->quote($limit_ts, "timestamp")." ";
4470 }
4471
4472 $q = "SELECT * FROM page_history ".
4473 " WHERE parent_id = ".$ilDB->quote($a_parent_id, "integer").
4474 " AND parent_type = ".$ilDB->quote($a_parent_type, "text").
4475 $and_str.$and_lang;
4476 $set = $ilDB->query($q);
4477 while ($page = $ilDB->fetchAssoc($set))
4478 {
4479 $page_changes[] = array(
4480 "date" => $page["hdate"],
4481 "id" => $page["page_id"],
4482 "lang" => $page["lang"],
4483 "type" => "hist",
4484 "nr" => $page["nr"],
4485 "user" => $page["user_id"]);
4486 }
4487
4488 $page_changes = ilUtil::sortArray($page_changes, "date", "desc");
4489
4490 return $page_changes;
4491 }
4492
4500 static function getAllPages($a_parent_type, $a_parent_id, $a_lang = "-")
4501 {
4502 global $ilDB;
4503
4504 $and_lang = "";
4505 if ($a_lang != "")
4506 {
4507 $and_lang = " AND lang = ".$ilDB->quote($a_lang, "text");
4508 }
4509
4510 $page_changes = array();
4511
4512 $q = "SELECT * FROM page_object ".
4513 " WHERE parent_id = ".$ilDB->quote($a_parent_id, "integer").
4514 " AND parent_type = ".$ilDB->quote($a_parent_type, "text").$and_lang;
4515 $set = $ilDB->query($q);
4516 $pages = array();
4517 while ($page = $ilDB->fetchAssoc($set))
4518 {
4519 $key_add = ($a_lang == "")
4520 ? ":".$page["lang"]
4521 : "";
4522 $pages[$page["page_id"].$key_add] = array(
4523 "date" => $page["last_change"],
4524 "id" => $page["page_id"],
4525 "lang" => $page["lang"],
4526 "user" => $page["last_change_user"]);
4527 }
4528
4529 return $pages;
4530 }
4531
4538 static function getNewPages($a_parent_type, $a_parent_id, $a_lang = "-")
4539 {
4540 global $ilDB;
4541
4542 $and_lang = "";
4543 if ($a_lang != "")
4544 {
4545 $and_lang = " AND lang = ".$ilDB->quote($a_lang, "text");
4546 }
4547
4548 $pages = array();
4549
4550 $q = "SELECT * FROM page_object ".
4551 " WHERE parent_id = ".$ilDB->quote($a_parent_id, "integer").
4552 " AND parent_type = ".$ilDB->quote($a_parent_type, "text").$and_lang.
4553 " ORDER BY created DESC";
4554 $set = $ilDB->query($q);
4555 while($page = $ilDB->fetchAssoc($set))
4556 {
4557 if ($page["created"] != "")
4558 {
4559 $pages[] = array(
4560 "created" => $page["created"],
4561 "id" => $page["page_id"],
4562 "lang" => $page["lang"],
4563 "user" => $page["create_user"],
4564 );
4565 }
4566 }
4567
4568 return $pages;
4569 }
4570
4577 static function getParentObjectContributors($a_parent_type, $a_parent_id, $a_lang = "-")
4578 {
4579 global $ilDB;
4580
4581 $and_lang = "";
4582 if ($a_lang != "")
4583 {
4584 $and_lang = " AND lang = ".$ilDB->quote($a_lang, "text");
4585 }
4586
4587 $contributors = array();
4588 $set = $ilDB->queryF("SELECT last_change_user, lang, page_id FROM page_object ".
4589 " WHERE parent_id = %s AND parent_type = %s ".
4590 " AND last_change_user != %s".$and_lang,
4591 array("integer", "text", "integer"),
4592 array($a_parent_id, $a_parent_type, 0));
4593
4594 while ($page = $ilDB->fetchAssoc($set))
4595 {
4596 if ($a_lang == "")
4597 {
4598 $contributors[$page["last_change_user"]][$page["page_id"]][$page["lang"]] = 1;
4599 }
4600 else
4601 {
4602 $contributors[$page["last_change_user"]][$page["page_id"]] = 1;
4603 }
4604 }
4605
4606 $set = $ilDB->queryF("SELECT count(*) as cnt, lang, page_id, user_id FROM page_history ".
4607 " WHERE parent_id = %s AND parent_type = %s AND user_id != %s ".$and_lang.
4608 " GROUP BY page_id, user_id, lang ",
4609 array("integer", "text", "integer"),
4610 array($a_parent_id, $a_parent_type, 0));
4611 while ($hpage = $ilDB->fetchAssoc($set))
4612 {
4613 if ($a_lang == "")
4614 {
4615 $contributors[$hpage["user_id"]][$hpage["page_id"]][$hpage["lang"]] =
4616 $contributors[$hpage["user_id"]][$hpage["page_id"]][$hpage["lang"]] + $hpage["cnt"];
4617 }
4618 else
4619 {
4620 $contributors[$hpage["user_id"]][$hpage["page_id"]] =
4621 $contributors[$hpage["user_id"]][$hpage["page_id"]] + $hpage["cnt"];
4622 }
4623 }
4624
4625 $c = array();
4626 foreach ($contributors as $k => $co)
4627 {
4628 if (ilObject::_lookupType($k) == "usr")
4629 {
4630 $name = ilObjUser::_lookupName($k);
4631 $c[] = array("user_id" => $k, "pages" => $co,
4632 "lastname" => $name["lastname"], "firstname" => $name["firstname"]);
4633 }
4634 }
4635
4636 return $c;
4637 }
4638
4645 static function getPageContributors($a_parent_type, $a_page_id, $a_lang = "-")
4646 {
4647 global $ilDB;
4648
4649 $and_lang = "";
4650 if ($a_lang != "")
4651 {
4652 $and_lang = " AND lang = ".$ilDB->quote($a_lang, "text");
4653 }
4654
4655 $contributors = array();
4656 $set = $ilDB->queryF("SELECT last_change_user, lang FROM page_object ".
4657 " WHERE page_id = %s AND parent_type = %s ".
4658 " AND last_change_user != %s".$and_lang,
4659 array("integer", "text", "integer"),
4660 array($a_page_id, $a_parent_type, 0));
4661
4662 while ($page = $ilDB->fetchAssoc($set))
4663 {
4664 if ($a_lang == "")
4665 {
4666 $contributors[$page["last_change_user"]][$page["lang"]] = 1;
4667 }
4668 else
4669 {
4670 $contributors[$page["last_change_user"]] = 1;
4671 }
4672 }
4673
4674 $set = $ilDB->queryF("SELECT count(*) as cnt, lang, page_id, user_id FROM page_history ".
4675 " WHERE page_id = %s AND parent_type = %s AND user_id != %s ".$and_lang.
4676 " GROUP BY user_id, page_id, lang ",
4677 array("integer", "text", "integer"),
4678 array($a_page_id, $a_parent_type, 0));
4679 while ($hpage = $ilDB->fetchAssoc($set))
4680 {
4681 if ($a_lang == "")
4682 {
4683 $contributors[$hpage["user_id"]][$page["lang"]] =
4684 $contributors[$hpage["user_id"]][$page["lang"]] + $hpage["cnt"];
4685 }
4686 else
4687 {
4688 $contributors[$hpage["user_id"]] =
4689 $contributors[$hpage["user_id"]] + $hpage["cnt"];
4690 }
4691 }
4692
4693 $c = array();
4694 foreach ($contributors as $k => $co)
4695 {
4696 include_once "Services/User/classes/class.ilObjUser.php";
4697 $name = ilObjUser::_lookupName($k);
4698 $c[] = array("user_id" => $k, "pages" => $co,
4699 "lastname" => $name["lastname"], "firstname" => $name["firstname"]);
4700 }
4701
4702 return $c;
4703 }
4704
4709 {
4710 global $ilDB;
4711
4712 $ilDB->update("page_object", array(
4713 "rendered_content" => array("clob", $a_content),
4714 "render_md5" => array("text", $a_md5),
4715 "rendered_time" => array("timestamp", ilUtil::now())
4716 ), array(
4717 "page_id" => array("integer", $this->getId()),
4718 "lang" => array("text", $this->getLanguage()),
4719 "parent_type" => array("text", $this->getParentType())
4720 ));
4721 }
4722
4730 static function getPagesWithLinks($a_parent_type, $a_parent_id, $a_lang = "-")
4731 {
4732 global $ilDB;
4733
4734 $page_changes = array();
4735
4736 $and_lang = "";
4737 if ($a_lang != "")
4738 {
4739 $and_lang = " AND lang = ".$ilDB->quote($a_lang, "text");
4740 }
4741
4742 $q = "SELECT * FROM page_object ".
4743 " WHERE parent_id = ".$ilDB->quote($a_parent_id, "integer").
4744 " AND parent_type = ".$ilDB->quote($a_parent_type, "text").
4745 " AND int_links = ".$ilDB->quote(1, "integer").$and_lang;
4746 $set = $ilDB->query($q);
4747 $pages = array();
4748 while ($page = $ilDB->fetchAssoc($set))
4749 {
4750 $key_add = ($a_lang == "")
4751 ? ":".$page["lang"]
4752 : "";
4753 $pages[$page["page_id"].$key_add] = array(
4754 "date" => $page["last_change"],
4755 "id" => $page["page_id"],
4756 "lang" => $page["lang"],
4757 "user" => $page["last_change_user"]);
4758 }
4759
4760 return $pages;
4761 }
4762
4770 {
4771 if (strpos($a_content, "IntLink"))
4772 {
4773 return true;
4774 }
4775 return false;
4776 }
4777
4782 {
4783 }
4784
4790// @todo begin: generalize
4791 function saveInitialOpenedContent($a_type, $a_id, $a_target)
4792 {
4793 $this->buildDom();
4794
4795 switch($a_type)
4796 {
4797 case "media":
4798 $link_type = "MediaObject";
4799 $a_id = "il__mob_".$a_id;
4800 break;
4801
4802 case "page":
4803 $link_type = "PageObject";
4804 $a_id = "il__pg_".$a_id;
4805 break;
4806
4807 case "term":
4808 $link_type = "GlossaryItem";
4809 $a_id = "il__git_".$a_id;
4810 $a_target = "Glossary";
4811 break;
4812 }
4813
4814 // if type or id missing -> delete InitOpenedContent, if existing
4815 if ($link_type == "" || $a_id == "")
4816 {
4817 $xpc = xpath_new_context($this->dom);
4818 $path = "//PageObject/InitOpenedContent";
4819 $res = xpath_eval($xpc, $path);
4820 if (count($res->nodeset) > 0)
4821 {
4822 $res->nodeset[0]->unlink_node($res->nodeset[0]);
4823 }
4824 }
4825 else
4826 {
4827 $xpc = xpath_new_context($this->dom);
4828 $path = "//PageObject/InitOpenedContent";
4829 $res = xpath_eval($xpc, $path);
4830 if (count($res->nodeset) > 0)
4831 {
4832 $init_node = $res->nodeset[0];
4833 $childs = $init_node->child_nodes();
4834 for($i = 0; $i < count($childs); $i++)
4835 {
4836 if ($childs[$i]->node_name() == "IntLink")
4837 {
4838 $il_node = $childs[$i];
4839 }
4840 }
4841 }
4842 else
4843 {
4844 $path = "//PageObject";
4845 $res = xpath_eval($xpc, $path);
4846 $page_node = $res->nodeset[0];
4847 $init_node = $this->dom->create_element("InitOpenedContent");
4848 $init_node = $page_node->append_child($init_node);
4849 $il_node = $this->dom->create_element("IntLink");
4850 $il_node = $init_node->append_child($il_node);
4851 }
4852 $il_node->set_attribute("Target", $a_id);
4853 $il_node->set_attribute("Type", $link_type);
4854 $il_node->set_attribute("TargetFrame", $a_target);
4855 }
4856
4857 $ret = $this->update();
4858 }
4859
4860
4867 {
4868 $this->buildDom();
4869
4870 $xpc = xpath_new_context($this->dom);
4871 $path = "//PageObject/InitOpenedContent";
4872 $res = xpath_eval($xpc, $path);
4873 $il_node = null;
4874 if (count($res->nodeset) > 0)
4875 {
4876 $init_node = $res->nodeset[0];
4877 $childs = $init_node->child_nodes();
4878 for($i = 0; $i < count($childs); $i++)
4879 {
4880 if ($childs[$i]->node_name() == "IntLink")
4881 {
4882 $il_node = $childs[$i];
4883 }
4884 }
4885 }
4886 if (!is_null($il_node))
4887 {
4888 $id = $il_node->get_attribute("Target");
4889 $link_type = $il_node->get_attribute("Type");
4890 $target = $il_node->get_attribute("TargetFrame");
4891
4892 switch($link_type)
4893 {
4894 case "MediaObject":
4895 $type = "media";
4896 break;
4897
4898 case "PageObject":
4899 $type = "page";
4900 break;
4901
4902 case "GlossaryItem":
4903 $type = "term";
4904 break;
4905 }
4906 include_once("./Services/Link/classes/class.ilInternalLink.php");
4908 return array("id" => $id, "type" => $type, "target" => $target);
4909 }
4910
4911 return array();
4912 }
4913// @todo end
4914
4925 function beforePageContentUpdate($a_page_content)
4926 {
4927
4928 }
4929
4937 function copy($a_id, $a_parent_type = "", $a_parent_id = 0, $a_clone_mobs = false)
4938 {
4939 if ($a_parent_type == "")
4940 {
4941 $a_parent_type = $this->getParentType();
4942 if ($a_parent_id == 0)
4943 {
4944 $a_parent_id = $this->getParentId();
4945 }
4946 }
4947
4948 include_once("./Services/COPage/classes/class.ilPageObjectFactory.php");
4949 foreach (self::lookupTranslations($this->getParentType(), $this->getId()) as $l)
4950 {
4951 $existed = false;
4952 $orig_page = ilPageObjectFactory::getInstance($this->getParentType(), $this->getId(), 0, $l);
4953 if (ilPageObject::_exists($a_parent_type, $a_id, $l))
4954 {
4955 $new_page_object = ilPageObjectFactory::getInstance($a_parent_type, $a_id, 0, $l);
4956 $existed = true;
4957 }
4958 else
4959 {
4960 $new_page_object = ilPageObjectFactory::getInstance($a_parent_type, 0, 0, $l);
4961 $new_page_object->setParentId($a_parent_id);
4962 $new_page_object->setId($a_id);
4963 }
4964 $new_page_object->setXMLContent($orig_page->copyXMLContent($a_clone_mobs));
4965 $new_page_object->setActive($orig_page->getActive());
4966 $new_page_object->setActivationStart($orig_page->getActivationStart());
4967 $new_page_object->setActivationEnd($orig_page->getActivationEnd());
4968 if ($existed)
4969 {
4970 $new_page_object->buildDom();
4971 $new_page_object->update();
4972 }
4973 else
4974 {
4975 $new_page_object->create();
4976 }
4977 }
4978
4979 }
4980
4988 static function lookupTranslations($a_parent_type, $a_id)
4989 {
4990 global $ilDB;
4991
4992 $set = $ilDB->query("SELECT lang FROM page_object ".
4993 " WHERE page_id = ".$ilDB->quote($a_id, "integer").
4994 " AND parent_type = ".$ilDB->quote($a_parent_type, "text")
4995 );
4996 $langs = array();
4997 while ($rec = $ilDB->fetchAssoc($set))
4998 {
4999 $langs[] = $rec["lang"];
5000 }
5001 return $langs;
5002 }
5003
5004
5010 function copyPageToTranslation($a_target_lang)
5011 {
5012 $transl_page = ilPageObjectFactory::getInstance($this->getParentType(),
5013 0, 0, $a_target_lang);
5014 $transl_page->setId($this->getId());
5015 $transl_page->setParentId($this->getParentId());
5016 $transl_page->setXMLContent($this->copyXMLContent());
5017 $transl_page->setActive($this->getActive());
5018 $transl_page->setActivationStart($this->getActivationStart());
5019 $transl_page->setActivationEnd($this->getActivationEnd());
5020 $transl_page->create();
5021 }
5022
5026
5030 function getEditLock()
5031 {
5032 global $ilUser, $ilDB;
5033 //return false;
5034 $aset = new ilSetting("adve");
5035
5036 $min = (int) $aset->get("block_mode_minutes") ;
5037 if ($min > 0)
5038 {
5039 // try to set the lock for the user
5040 $ts = time();
5041 $ilDB->manipulate("UPDATE page_object SET ".
5042 " edit_lock_user = ".$ilDB->quote($ilUser->getId(), "integer").",".
5043 " edit_lock_ts = ".$ilDB->quote($ts, "integer").
5044 " WHERE (edit_lock_user = ".$ilDB->quote($ilUser->getId(), "integer")." OR ".
5045 " edit_lock_ts < ".$ilDB->quote(time() - ($min * 60), "integer").") ".
5046 " AND page_id = ".$ilDB->quote($this->getId(), "integer").
5047 " AND parent_type = ".$ilDB->quote($this->getParentType(), "text")
5048 );
5049
5050 $set = $ilDB->query("SELECT edit_lock_user FROM page_object ".
5051 " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
5052 " AND parent_type = ".$ilDB->quote($this->getParentType(), "text")
5053 );
5054 $rec = $ilDB->fetchAssoc($set);
5055 if ($rec["edit_lock_user"] != $ilUser->getId())
5056 {
5057 return false;
5058 }
5059 }
5060
5061 return true;
5062 }
5063
5068 {
5069 global $ilUser, $ilDB;
5070
5071 $aset = new ilSetting("adve");
5072
5073 $min = (int) $aset->get("block_mode_minutes") ;
5074 if ($min > 0)
5075 {
5076 // try to set the lock for the user
5077 $ts = time();
5078 $ilDB->manipulate("UPDATE page_object SET ".
5079 " edit_lock_user = ".$ilDB->quote($ilUser->getId(), "integer").",".
5080 " edit_lock_ts = 0".
5081 " WHERE edit_lock_user = ".$ilDB->quote($ilUser->getId(), "integer").
5082 " AND page_id = ".$ilDB->quote($this->getId(), "integer").
5083 " AND parent_type = ".$ilDB->quote($this->getParentType(), "text")
5084 );
5085
5086 $set = $ilDB->query("SELECT edit_lock_user FROM page_object ".
5087 " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
5088 " AND parent_type = ".$ilDB->quote($this->getParentType(), "text")
5089 );
5090 $rec = $ilDB->fetchAssoc($set);
5091 if ($rec["edit_lock_user"] != $ilUser->getId())
5092 {
5093 return false;
5094 }
5095 }
5096
5097 return true;
5098 }
5099
5106 {
5107 global $ilDB;
5108
5109 $aset = new ilSetting("adve");
5110 $min = (int) $aset->get("block_mode_minutes");
5111
5112 $set = $ilDB->query("SELECT edit_lock_user, edit_lock_ts FROM page_object ".
5113 " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
5114 " AND parent_type = ".$ilDB->quote($this->getParentType(), "text")
5115 );
5116 $rec = $ilDB->fetchAssoc($set);
5117 $rec["edit_lock_until"] = $rec["edit_lock_ts"] + $min * 60;
5118
5119 return $rec;
5120 }
5121
5134 public static function truncateHTML($a_text, $a_length = 100, $a_ending = '...', $a_exact = false, $a_consider_html = true)
5135 {
5136 include_once "Services/Utilities/classes/class.ilStr.php";
5137
5138 if ($a_consider_html)
5139 {
5140 // if the plain text is shorter than the maximum length, return the whole text
5141 if(strlen(preg_replace('/<.*?>/', '', $a_text)) <= $a_length)
5142 {
5143 return $a_text;
5144 }
5145
5146 // splits all html-tags to scanable lines
5147 $total_length = strlen($a_ending);
5148 $open_tags = array();
5149 $truncate = '';
5150 preg_match_all('/(<.+?>)?([^<>]*)/s', $a_text, $lines, PREG_SET_ORDER);
5151 foreach($lines as $line_matchings)
5152 {
5153 // if there is any html-tag in this line, handle it and add it (uncounted) to the output
5154 if(!empty($line_matchings[1]))
5155 {
5156 // if it's an "empty element" with or without xhtml-conform closing slash
5157 if(preg_match('/^<(\s*.+?\/\s*|\s*(img|br|input|hr|area|base|basefont|col|frame|isindex|link|meta|param)(\s.+?)?)>$/is', $line_matchings[1]))
5158 {
5159 // do nothing
5160 }
5161 // if tag is a closing tag
5162 else if(preg_match('/^<\s*\/([^\s]+?)\s*>$/s', $line_matchings[1], $tag_matchings))
5163 {
5164 // delete tag from $open_tags list
5165 $pos = array_search($tag_matchings[1], $open_tags);
5166 if ($pos !== false)
5167 {
5168 unset($open_tags[$pos]);
5169 }
5170 }
5171 // if tag is an opening tag
5172 else if (preg_match('/^<\s*([^\s>!]+).*?>$/s', $line_matchings[1], $tag_matchings))
5173 {
5174 // add tag to the beginning of $open_tags list
5175 array_unshift($open_tags, strtolower($tag_matchings[1]));
5176 }
5177 // add html-tag to $truncate'd text
5178 $truncate .= $line_matchings[1];
5179 }
5180
5181 // calculate the length of the plain text part of the line; handle entities as one character
5182 $content_length = strlen(preg_replace('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|[0-9a-f]{1,6};/i', ' ', $line_matchings[2]));
5183 if($total_length+$content_length > $a_length)
5184 {
5185 // the number of characters which are left
5186 $left = $a_length - $total_length;
5187 $entities_length = 0;
5188 // search for html entities
5189 if(preg_match_all('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|[0-9a-f]{1,6};/i', $line_matchings[2], $entities, PREG_OFFSET_CAPTURE))
5190 {
5191 // calculate the real length of all entities in the legal range
5192 foreach($entities[0] as $entity)
5193 {
5194 if($entity[1]+1-$entities_length <= $left)
5195 {
5196 $left--;
5197 $entities_length += strlen($entity[0]);
5198 }
5199 else
5200 {
5201 // no more characters left
5202 break;
5203 }
5204 }
5205 }
5206
5207 // $truncate .= substr($line_matchings[2], 0, $left+$entities_length);
5208 $truncate .= ilStr::shortenText($line_matchings[2], 0, $left+$entities_length);
5209
5210 // maximum lenght is reached, so get off the loop
5211 break;
5212 }
5213 else
5214 {
5215 $truncate .= $line_matchings[2];
5216 $total_length += $content_length;
5217 }
5218
5219 // if the maximum length is reached, get off the loop
5220 if($total_length >= $a_length)
5221 {
5222 break;
5223 }
5224 }
5225 }
5226 else
5227 {
5228 if(strlen($a_text) <= $a_length)
5229 {
5230 return $a_text;
5231 }
5232 else
5233 {
5234 // $truncate = substr($a_text, 0, $a_length - strlen($a_ending));
5235 $truncate = ilStr::shortenText($a_text, 0, $a_length - strlen($a_ending));
5236 }
5237 }
5238
5239 // THIS IS BUGGY AS IT MIGHT BREAK AN OPEN TAG AT THE END
5240 if(!sizeof($open_tags))
5241 {
5242 // if the words shouldn't be cut in the middle...
5243 if (!$a_exact)
5244 {
5245 // ...search the last occurance of a space...
5246 $spacepos = strrpos($truncate, ' ');
5247 if($spacepos !== false)
5248 {
5249 // ...and cut the text in this position
5250 // $truncate = substr($truncate, 0, $spacepos);
5251 $truncate = ilStr::shortenText($truncate, 0, $spacepos);
5252 }
5253 }
5254 }
5255
5256 // add the defined ending to the text
5257 $truncate .= $a_ending;
5258
5259 if($a_consider_html)
5260 {
5261 // close all unclosed html-tags
5262 foreach($open_tags as $tag)
5263 {
5264 $truncate .= '</'.$tag.'>';
5265 }
5266 }
5267
5268 return $truncate;
5269 }
5270
5277 {
5278 return array();
5279 }
5280
5288 static function getLastChangeByParent($a_parent_type, $a_parent_id, $a_lang = "")
5289 {
5290 global $ilDB;
5291
5292 $and_lang = "";
5293 if ($a_lang != "")
5294 {
5295 $and_lang = " AND lang = ".$ilDB->quote($a_lang, "text");
5296 }
5297
5298 $ilDB->setLimit(1);
5299 $q = "SELECT last_change FROM page_object ".
5300 " WHERE parent_id = ".$ilDB->quote($a_parent_id, "integer").
5301 " AND parent_type = ".$ilDB->quote($a_parent_type, "text").$and_lang.
5302 " ORDER BY last_change DESC";
5303
5304 $set = $ilDB->query($q);
5305 $rec = $ilDB->fetchAssoc($set);
5306
5307 return $rec["last_change"];
5308 }
5309
5316 {
5317 $file_obj_ids = array();
5318
5319 // insert inst id file item identifier entries
5320 $xpc = xpath_new_context($this->dom);
5321 $path = "//FileItem/Identifier";
5322 $res = xpath_eval($xpc, $path);
5323 for($i = 0; $i < count($res->nodeset); $i++)
5324 {
5325 $file_obj_ids[] = $res->nodeset[$i]->get_attribute("Entry");
5326 }
5327 unset($xpc);
5328 return $file_obj_ids;
5329 }
5330
5335 public function resolveResources($ref_mapping)
5336 {
5337 include_once("./Services/COPage/classes/class.ilPCResources.php");
5338 return ilPCResources::resolveResources($this, $ref_mapping);
5339 }
5340
5341
5342
5343}
5344?>
date( 'd-M-Y', $objPHPExcel->getProperties() ->getCreated())
$error
Definition: Error.php:17
$size
Definition: RandomTest.php:79
$files
Definition: add-vimline.php:18
global $l
Definition: afr.php:30
$path
Definition: aliased.php:25
$_GET["client_id"]
$_POST["username"]
An exception for terminatinating execution or to throw for unit testing.
const IL_CAL_UNIX
const IL_CAL_DATETIME
const IL_MODE_OUTPUT
const IL_INSERT_BEFORE
const IL_INSERT_CHILD
const IL_INSERT_AFTER
static _instantiateQuestion($question_id)
static getPCDefinitions()
Get PC definitions.
static getPCDefinitionByName($a_pc_name)
Get PC definition by name.
static requirePCClassByName($a_name)
Get instance.
static formatDate(ilDateTime $date)
Format a date @access public.
@classDescription Date and time handling
static _after(ilDateTime $start, ilDateTime $end, $a_compare_field='', $a_tz='')
compare two dates and check start is after end This method does not consider tz offsets.
static _before(ilDateTime $start, ilDateTime $end, $a_compare_field='', $a_tz='')
compare two dates and check start is before end This method does not consider tz offsets.
static setAction($a_action)
static _lookupType($a_obj_id, $a_lm_id=0)
Lookup type.
Extension of ilPageObject for learning modules.
static getLogger($a_component_id)
Get component logger.
Class ilMediaAliasItem.
static _resolveMapAreaLinks($a_mob_id)
resolve internal links of all media items of a media object
static _getMapAreasIntLinks($a_mob_id)
get all internal links of map areas of a mob
static deleteNewsOfContext($a_context_obj_id, $a_context_obj_type, $a_context_sub_obj_id=0, $a_context_sub_obj_type="")
Delete all news of a context.
static _lookupFileSize($a_id)
Lookups the file size of the file in bytes.
static _getFilesOfObject($a_type, $a_id, $a_usage_hist_nr=0, $a_usage_lang="-")
get all files of an object
Class ilObjMediaObject.
static _deleteAllUsages($a_type, $a_id, $a_usage_hist_nr=0, $a_lang="-")
static
static _getMobsOfObject($a_type, $a_id, $a_usage_hist_nr=0, $a_lang="-")
get mobs of object
static _lookupName($a_user_id)
lookup user name
static _lookupObjId($a_id)
static _lookupImportId($a_obj_id)
static _exists($a_id, $a_reference=false, $a_type=null)
checks if an object exists in object_data@access public
static _getLastUpdateOfObjects($a_objs)
Get last update for a set of media objects.
static _lookupType($a_id, $a_reference=false)
lookup object type
Class ilPCDataTable.
Class ilPCMediaObject.
Class ilPCParagraph.
static xml2output($a_text, $a_wysiwyg=false, $a_replace_lists=true)
Converts xml from DB to output in edit textarea.
static resolveResources(ilPageObject $page, $ref_mappings)
Resolve resources.
Class ilPCTable.
static incEdId($ed_id)
Increases an hierarchical editing id at lowest level (last number)
static sortHierIds($a_array)
Sort an array of Hier IDS in ascending order.
static getInstance($a_parent_type, $a_id=0, $a_old_nr=0, $a_lang="-")
Get page object instance.
static getConfigInstance($a_parent_type)
Get page config instance.
Class ilPageObject.
releasePageLock()
Release page lock.
stripHierIDs()
strip all hierarchical id attributes out of the dom tree
switchEnableMultiple($a_hids, $a_update=true, $a_self_ass=false)
(De-)activate elements
moveContentBefore($a_source, $a_target, $a_spcid="", $a_tpcid="")
move content object from position $a_source before position $a_target (both hierarchical content ids)
getEditLockInfo()
Get edit lock info.
getRenderedContent()
Get Rendered Content.
resolveResources($ref_mapping)
Resolve resources.
removeQuestions(&$temp_dom)
Remove questions from document.
setRenderedContent($a_renderedcontent)
Set Rendered Content.
getOfflineHandler()
Get offline handler.
__beforeDelete()
Before deletion handler (internal).
static truncateHTML($a_text, $a_length=100, $a_ending='...', $a_exact=false, $a_consider_html=true)
Truncate (html) string.
getRenderMd5()
Get Render MD5.
deleteStyleUsages($a_old_nr=0)
Delete style usages.
__construct($a_id=0, $a_old_nr=0, $a_lang="-")
Constructor @access public.
initPageConfig()
Init page config.
read()
Read page data.
getLastChangeUser()
Get last change user.
containsIntLinks($a_content)
Check whether content contains internal links.
static getPageContributors($a_parent_type, $a_page_id, $a_lang="-")
Get all contributors for parent object.
registerOfflineHandler($handler)
static getNewPages($a_parent_type, $a_parent_id, $a_lang="-")
Get new pages.
static _existsAndNotEmpty($a_parent_type, $a_id, $a_lang="-")
Checks whether page exists and is not empty (may return true on some empty pages)
getFirstColumnIds()
get ids of all first table columns
setActivationEnd($a_activationend)
Set Activation End.
getHistoryInfo($a_nr)
Get information about a history entry, its predecessor and its successor.
saveInitialOpenedContent($a_type, $a_id, $a_target)
Save initial opened content.
addFileSizes()
add file sizes
deleteInternalLinks()
Delete internal links.
deleteContent($a_hid, $a_update=true, $a_pcid="")
delete content object with hierarchical id $a_hid
static _lookupActive($a_id, $a_parent_type, $a_check_scheduled_activation=false, $a_lang="-")
lookup activation status
getLanguage()
Get language.
getPageConfig()
Get page config object.
setContainsIntLink($a_contains_link)
lm parser set this flag to true, if the page contains intern links (this method should only be called...
pasteContents($a_hier_id, $a_self_ass=false)
Paste contents from pc clipboard.
__afterHistoryEntry($a_old_domdoc, $a_old_content, $a_old_nr)
Before deletion handler (internal).
getEditLock()
Get page lock.
setImportMode($a_val)
Set import mode.
addUpdateListener(&$a_object, $a_method, $a_parameters="")
insertInstIntoIDs($a_inst, $a_res_ref_to_obj_id=true)
inserts installation id into ids (e.g.
afterUpdate()
After update.
setLanguage($a_val)
Set language.
newMobCopies($temp_dom)
Replaces media objects with copies.
getInitialOpenedContent()
Get initial opened content.
create()
create new page (with current xml data)
countPageContents()
Remove questions from document.
saveStyleUsage($a_domdoc, $a_old_nr=0)
Save all style class/template usages.
setActivationStart($a_activationstart)
Set Activation Start.
insertContentNode(&$a_cont_node, $a_pos, $a_mode=IL_INSERT_AFTER, $a_pcid="")
insert a content node before/after a sibling or as first child of a parent
deleteContentBeforeHierId($a_hid, $a_update=true)
delete content object with hierarchical id < $a_hid
increaseViewCnt()
Increase view cnt.
static _handleImportRepositoryLinks($a_rep_import_id, $a_rep_type, $a_rep_ref_id)
Change targest of repository links.
updateFromXML()
Updates page object with current xml content.
insertContent(&$a_cont_obj, $a_pos, $a_mode=IL_INSERT_AFTER, $a_pcid="")
insert a content node before/after a sibling or as first child of a parent
buildDom($a_force=false)
setRenderedTime($a_renderedtime)
Set Rendered Time.
getContainsQuestion()
Get contains question.
existsPCId($a_pc_id)
existsPCId
getActivationEnd()
Get Activation End.
deleteContentFromHierId($a_hid, $a_update=true)
delete content object with hierarchical id >= $a_hid
getXMLContent($a_incl_head=false)
get xml content of page
getLastUpdateOfIncludedElements()
Get last update of included elements (media objects and files).
afterConstructor()
After constructor.
static _lookupContainsDeactivatedElements($a_id, $a_parent_type, $a_lang="-")
lookup whether page contains deactivated elements
validateDom()
Validate the page content agains page DTD.
cutContents($a_hids)
Copy contents to clipboard and cut them from the page.
resolveFileItems($a_mapping)
Resolve file items (after import)
setLastChange($a_lastchange)
Set Last Change.
resolveMediaAliases($a_mapping, $a_reuse_existing_by_import=false)
Resolve media aliases (after import)
handleImportRepositoryLink($a_rep_import_id, $a_rep_type, $a_rep_ref_id)
static lookupParentId($a_id, $a_type)
Lookup parent id.
getHierIds()
get all hierarchical ids
resolveIntLinks($a_link_map=null)
Resolves all internal link targets of the page, if targets are available (after import)
appendLangVarXML(&$xml, $var)
containsIntLink()
returns true, if page was marked as containing an intern link (via setContainsIntLink) (this method s...
setShowActivationInfo($a_val)
Set show page activation info.
generatePcId($a_pc_ids=false)
Generate new pc id.
setRenderMd5($a_rendermd5)
Set Render MD5.
newQuestionCopies(&$temp_dom)
Replaces existing question content elements with new copies.
getActivationStart()
Get Activation Start.
getMultimediaXML()
get a xml string that contains all media object elements, that are referenced by any media alias in t...
getParentType()
Get parent type.
static _lookupActivationData($a_id, $a_parent_type, $a_lang="-")
Lookup activation data.
static lookupTranslations($a_parent_type, $a_id)
Lookup translations.
getContentObject($a_hier_id, $a_pc_id="")
Get a content object of the page.
saveInternalLinks($a_domdoc)
save internal links of page
handleRepositoryLinksOnCopy($a_mapping, $a_source_ref_id)
Handle repository links on copy process.
static getPagesWithLinks($a_parent_type, $a_parent_id, $a_lang="-")
Get all pages for parent object that contain internal links.
getPageContentsHashes()
Get page contents hashes.
getHistoryEntry($a_old_nr)
Get History Entry.
getContentTemplates()
Get content templates.
static _exists($a_parent_type, $a_id, $a_lang="", $a_no_cache=false)
Checks whether page exists.
static getAllPages($a_parent_type, $a_parent_id, $a_lang="-")
Get all pages for parent object.
setXMLContent($a_xml, $a_encoding="UTF-8")
set xml content of page, start with <PageObject...>, end with </PageObject>, comply with ILIAS DTD,...
setPageConfig($a_val)
Set page config object.
collectMediaObjects($a_inline_only=true)
get all media objects, that are referenced and used within the page
getAllFileObjIds()
Get all file object ids.
moveIntLinks($a_from_to)
Move internal links from one destination to another.
getFirstRowIds()
get ids of all first table rows
getMediaAliasElement($a_mob_id, $a_nr=1)
get complete media object (alias) element
getQuestionIds()
Get question ids.
checkPCIds()
Check, whether (all) page content hashes are set.
getDom()
Deprecated php4DomDocument.
getDomDoc()
Get dom doc (php5 dom document)
copy($a_id, $a_parent_type="", $a_parent_id=0, $a_clone_mobs=false)
Copy page.
copyXmlContent($a_clone_mobs=false)
Copy content of page; replace page components with copies where necessary (e.g.
getXMLFromDom($a_incl_head=false, $a_append_mobs=false, $a_append_bib=false, $a_append_str="", $a_omit_pageobject_tag=false)
get xml content of page from dom (use this, if any changes are made to the document)
getFO()
get fo page content
copyPageToTranslation($a_target_lang)
Copy page to translation.
setActive($a_active)
set activation
addHierIDs()
Add hierarchical ID (e.g.
checkForTag($a_content_tag, $a_hier_id, $a_pc_id="")
Get content node from dom.
setId($a_id)
set id
insertPCIds()
Insert Page Content IDs.
containsDeactivatedElements($a_content)
Check whether content contains deactivated elements.
compareVersion($a_left, $a_right)
Compares to revisions of the page.
getAllPCIds()
Get all pc ids.
performAutomaticModifications()
Perform automatic modifications (may be overwritten by sub classes)
getFileItemIds()
get ids of all file items
getHistoryEntries()
Get History Entries.
static getParentObjectContributors($a_parent_type, $a_parent_id, $a_lang="-")
Get all contributors for parent object.
getLastChange()
Get Last Change.
lookforhier($a_hier_id)
getShowActivationInfo()
Get show page activation info.
resolveQuestionReferences($a_mapping)
Resolve all quesion references (after import)
bbCode2XML(&$a_content)
transforms bbCode to corresponding xml
& getContentNode($a_hier_id, $a_pc_id="")
Get content node from dom.
static getRecentChanges($a_parent_type, $a_parent_id, $a_period=30, $a_lang="")
Get recent pages changes for parent object.
handleCopiedContent($a_dom, $a_self_ass=true, $a_clone_mobs=false)
Handle copied content.
writeRenderedContent($a_content, $a_md5)
Write rendered content.
getLanguageVariablesXML()
Get language variables as XML.
needsImportParsing($a_parse="")
static preloadActivationDataByParentId($a_parent_id)
Preload activation data by Parent Id.
addChangeDivClasses($a_hashes)
getListItemIds()
get ids of all list items
static getLastChangeByParent($a_parent_type, $a_parent_id, $a_lang="")
Get all pages for parent object.
createFromXML()
Create new page object with current xml content.
newIIMCopies($temp_dom)
Replaces media objects in interactive images with copies of the interactive images.
__afterUpdate($a_domdoc, $a_xml, $a_creation=false, $a_empty=false)
After update event handler (internal).
static _writeActive($a_id, $a_parent_type, $a_active, $a_reset_scheduled_activation=true, $a_lang="-")
write activation status
getHierIdsForPCIds($a_pc_ids)
Get hier ids for a set of pc ids.
static _isScheduledActivation($a_id, $a_parent_type, $a_lang="-")
Check whether page is activated by time schedule.
copyContents($a_hids)
Copy contents to clipboard.
beforePageContentUpdate($a_page_content)
Before page content update.
update($a_validate=true, $a_no_history=false)
update complete page content in db (dom xml content is used)
static _writeParentId($a_parent_type, $a_pg_id, $a_par_id)
Write parent id.
getImportMode()
Get import mode.
appendXMLContent($a_xml)
append xml content to page setXMLContent must be called before and the same encoding must be used
deleteContents($a_hids, $a_update=true, $a_self_ass=false)
Delete multiple content objects.
getInternalLinks($a_cnt_multiple=false)
get all internal links that are used within the page
setContainsQuestion($a_val)
Set contains question.
moveContentAfter($a_source, $a_target, $a_spcid="", $a_tpcid="")
move content object from position $a_source before position $a_target (both hierarchical content ids)
getRenderedTime()
Get Rendered Time.
send_paragraph($par_id, $filename)
setLastChangeUser($a_val)
Set last change user.
resolveIIMMediaAliases($a_mapping)
Resolve iim media aliases (in ilContObjParse)
getActive($a_check_scheduled_activation=false)
get activation
setParagraphContent($a_hier_id, $a_content)
Set content of paragraph.
static _moveContentAfterHierId(&$a_source_page, &$a_target_page, $a_hid)
move content of hierarchical id >= $a_hid to other page
static _existsAndNotEmpty($a_parent_type, $a_id, $a_lang="-")
checks whether page exists and is not empty (may return true on some empty pages)
ILIAS Setting Class.
static shortenText($a_string, $a_start_pos, $a_num_bytes, $a_encoding='UTF-8')
Shorten text to the given number of bytes.
static getNamePresentation($a_user_id, $a_user_image=false, $a_profile_link=false, $a_profile_back_link="", $a_force_first_lastname=false, $a_omit_login=false, $a_sortable=true, $a_return_data_array=false)
Default behaviour is:
static sortArray($array, $a_array_sortby, $a_array_sortorder=0, $a_numeric=false, $a_keep_keys=false)
sortArray
static deliverData($a_data, $a_filename, $mime="application/octet-stream", $charset="")
deliver data for download via browser.
static now()
Return current timestamp in Y-m-d H:i:s format.
$h
$params
Definition: example_049.php:96
$target_arr
Definition: goto.php:49
global $ilCtrl
Definition: ilias.php:18
const ILIAS_VERSION_NUMERIC
xslt_free(&$proc)
xslt_create()
xpath_eval($xpath_context, $eval_str, $contextnode=null)
domxml_open_mem($str, $mode=0, &$error=NULL)
xpath_new_context($dom_document)
redirection script todo: (a better solution should control the processing via a xml file)
$ret
Definition: parser.php:6
global $lng
Definition: privfeed.php:17
$ref_id
Definition: sahs_server.php:39
global $ilDB
$lm_set
$errors
if(!is_array($argv)) $options
$mobs
$ilUser
Definition: imgupload.php:18
$a_content
Definition: workflow.php:94
$a_type
Definition: workflow.php:93