ILIAS  release_5-1 Revision 5.0.0-5477-g43f3e3fab5f
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_1.dtd";
66 var $language = "-";
67 static protected $activation_data = array();
68 protected $import_mode = false;
69
73 protected $log;
74
79 final public function ilPageObject($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().").");
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 $this->dom = @domxml_open_mem($this->getXMLContent(true), DOMXML_LOAD_VALIDATING, $error);
420
421 $xpc = xpath_new_context($this->dom);
422 $path = "//PageObject";
423 $res =& xpath_eval($xpc, $path);
424 if (count($res->nodeset) == 1)
425 {
426 $this->node =& $res->nodeset[0];
427 }
428
429 if (empty($error))
430 {
431 $this->dom_builded = true;
432 return true;
433 }
434 else
435 {
436 return $error;
437 }
438 }
439
440 function freeDom()
441 {
442 //$this->dom->free();
443 unset($this->dom);
444 }
445
449 function getDom()
450 {
451 return $this->dom;
452 }
453
460 function getDomDoc()
461 {
462 if ($this->dom instanceof php4DOMDocument)
463 {
464 return $this->dom->myDOMDocument;
465 }
466
467 return $this->dom;
468 }
469
470
474 function setId($a_id)
475 {
476 $this->id = $a_id;
477 }
478
479 function getId()
480 {
481 return $this->id;
482 }
483
484 function setParentId($a_id)
485 {
486 $this->parent_id = $a_id;
487 }
488
489 function getParentId()
490 {
491 return $this->parent_id;
492 }
493
494 function addUpdateListener(&$a_object, $a_method, $a_parameters = "")
495 {
497 $this->update_listeners[$cnt]["object"] =& $a_object;
498 $this->update_listeners[$cnt]["method"] = $a_method;
499 $this->update_listeners[$cnt]["parameters"] = $a_parameters;
500 $this->update_listener_cnt++;
501 }
502
504 {
505 for($i=0; $i<$this->update_listener_cnt; $i++)
506 {
507 $object =& $this->update_listeners[$i]["object"];
508 $method = $this->update_listeners[$i]["method"];
509 $parameters = $this->update_listeners[$i]["parameters"];
510 $object->$method($parameters);
511 }
512 }
513
519 function setActive($a_active)
520 {
521 $this->active = $a_active;
522 }
523
529 function getActive($a_check_scheduled_activation = false)
530 {
531 if ($a_check_scheduled_activation && !$this->active)
532 {
533 include_once("./Services/Calendar/classes/class.ilDateTime.php");
534 $start = new ilDateTime($this->getActivationStart(), IL_CAL_DATETIME);
535 $end = new ilDateTime($this->getActivationEnd(), IL_CAL_DATETIME);
536 $now = new ilDateTime(time(), IL_CAL_UNIX);
537 if (!ilDateTime::_before($now, $start) && !ilDateTime::_after($now, $end))
538 {
539 return true;
540 }
541 }
542 return $this->active;
543 }
544
550 static function preloadActivationDataByParentId($a_parent_id)
551 {
552 global $ilDB;
553
554 $set = $ilDB->query("SELECT page_id, parent_type, lang, active, activation_start, activation_end, show_activation_info FROM page_object ".
555 " WHERE parent_id = ".$ilDB->quote($a_parent_id, "integer")
556 );
557 while ($rec = $ilDB->fetchAssoc($set))
558 {
559 self::$activation_data[$rec["page_id"].":".$rec["parent_type"].":".$rec["lang"]] = $rec;
560 }
561 }
562
563
567 static function _lookupActive($a_id, $a_parent_type, $a_check_scheduled_activation = false, $a_lang = "-")
568 {
569 global $ilDB;
570
571 // language must be set at least to "-"
572 if ($a_lang == "")
573 {
574 $a_lang = "-";
575 }
576
577 if (isset(self::$activation_data[$a_id.":".$a_parent_type.":".$a_lang]))
578 {
579 $rec = self::$activation_data[$a_id.":".$a_parent_type.":".$a_lang];
580 }
581 else
582 {
583 $set = $ilDB->queryF("SELECT active, activation_start, activation_end FROM page_object WHERE page_id = %s".
584 " AND parent_type = %s AND lang = %s",
585 array("integer", "text", "text"),
586 array($a_id, $a_parent_type, $a_lang));
587 $rec = $ilDB->fetchAssoc($set);
588 }
589
590
591 $rec["n"] = ilUtil::now();
592
593 if (!$rec["active"] && $a_check_scheduled_activation)
594 {
595 if ($rec["n"] >= $rec["activation_start"] &&
596 $rec["n"] <= $rec["activation_end"])
597 {
598 return true;
599 }
600 }
601
602 return $rec["active"];
603 }
604
608 static function _isScheduledActivation($a_id, $a_parent_type, $a_lang = "-")
609 {
610 global $ilDB;
611
612 // language must be set at least to "-"
613 if ($a_lang == "")
614 {
615 $a_lang = "-";
616 }
617
618//echo "<br>";
619//var_dump(self::$activation_data); exit;
620 if (isset(self::$activation_data[$a_id.":".$a_parent_type.":".$a_lang]))
621 {
622 $rec = self::$activation_data[$a_id.":".$a_parent_type.":".$a_lang];
623 }
624 else
625 {
626 $set = $ilDB->queryF("SELECT active, activation_start, activation_end FROM page_object WHERE page_id = %s".
627 " AND parent_type = %s AND lang = %s", array("integer", "text", "text"),
628 array($a_id, $a_parent_type, $a_lang));
629 $rec = $ilDB->fetchAssoc($set);
630 }
631
632 if (!$rec["active"] && $rec["activation_start"] != "")
633 {
634 return true;
635 }
636
637 return false;
638 }
639
643 function _writeActive($a_id, $a_parent_type, $a_active, $a_reset_scheduled_activation = true, $a_lang = "-")
644 {
645 global $ilDB;
646
647 // language must be set at least to "-"
648 if ($a_lang == "")
649 {
650 $a_lang = "-";
651 }
652
653 if ($a_reset_scheduled_activation)
654 {
655 $st = $ilDB->manipulateF("UPDATE page_object SET active = %s, activation_start = %s, ".
656 " activation_end = %s WHERE page_id = %s".
657 " AND parent_type = %s AND lang = %s", array("boolean", "timestamp", "timestamp", "integer", "text", "text"),
658 array($a_active, null, null, $a_id, $a_parent_type, $a_lang));
659 }
660 else
661 {
662 $st = $ilDB->prepareManip("UPDATE page_object SET active = %s WHERE page_id = %s".
663 " AND parent_type = %s AND lang = %s", array("boolean", "integer", "text", "text"),
664 array($a_active, $a_id, $a_parent_type, $a_lang));
665 }
666 }
667
671 function _lookupActivationData($a_id, $a_parent_type, $a_lang = "-")
672 {
673 global $ilDB;
674
675 // language must be set at least to "-"
676 if ($a_lang == "")
677 {
678 $a_lang = "-";
679 }
680
681 if (isset(self::$activation_data[$a_id.":".$a_parent_type.":".$a_lang]))
682 {
683 $rec = self::$activation_data[$a_id.":".$a_parent_type.":".$a_lang];
684 }
685 else
686 {
687 $set = $ilDB->queryF("SELECT active, activation_start, activation_end, show_activation_info FROM page_object WHERE page_id = %s".
688 " AND parent_type = %s AND lang = %s",
689 array("integer", "text", "text"),
690 array($a_id, $a_parent_type, $a_lang));
691 $rec = $ilDB->fetchAssoc($set);
692 }
693
694 return $rec;
695 }
696
697
701 static function lookupParentId($a_id, $a_type)
702 {
703 global $ilDB;
704
705 $res = $ilDB->query("SELECT parent_id FROM page_object WHERE page_id = ".$ilDB->quote($a_id, "integer")." ".
706 "AND parent_type=".$ilDB->quote($a_type, "text"));
707 $rec = $ilDB->fetchAssoc($res);
708 return $rec["parent_id"];
709 }
710
714 function _writeParentId($a_parent_type, $a_pg_id, $a_par_id)
715 {
716 global $ilDB;
717
718 $st = $ilDB->manipulateF("UPDATE page_object SET parent_id = %s WHERE page_id = %s".
719 " AND parent_type = %s", array("integer", "integer", "text"),
720 array($a_par_id, $a_pg_id, $a_parent_type));
721 }
722
728 function setActivationStart($a_activationstart)
729 {
730 if ($a_activationstart == "")
731 {
732 $a_activationstart = null;
733 }
734 $this->activationstart = $a_activationstart;
735 }
736
743 {
744 return $this->activationstart;
745 }
746
752 function setActivationEnd($a_activationend)
753 {
754 if ($a_activationend == "")
755 {
756 $a_activationend = null;
757 }
758 $this->activationend = $a_activationend;
759 }
760
767 {
768 return $this->activationend;
769 }
770
779 function getContentObject($a_hier_id, $a_pc_id = "")
780 {
781 $cont_node = $this->getContentNode($a_hier_id, $a_pc_id);
782 if (!is_object($cont_node))
783 {
784 return false;
785 }
786 include_once("./Services/COPage/classes/class.ilCOPagePCDef.php");
787 $node_name = $cont_node->node_name();
788 if ($node_name == "PageObject")
789 {
790 return null;
791 }
792 if ($node_name == "PageContent")
793 {
794 $child_node = $cont_node->first_child();
795 $node_name = $child_node->node_name();
796 }
797
798 // table extra handling (@todo: get rid of it)
799 if ($node_name == "Table")
800 {
801 if ($child_node->get_attribute("DataTable") == "y")
802 {
803 require_once("./Services/COPage/classes/class.ilPCDataTable.php");
804 $tab = new ilPCDataTable($this);
805 $tab->setNode($cont_node);
806 $tab->setHierId($a_hier_id);
807 }
808 else
809 {
810 require_once("./Services/COPage/classes/class.ilPCTable.php");
811 $tab = new ilPCTable($this);
812 $tab->setNode($cont_node);
813 $tab->setHierId($a_hier_id);
814 }
815 $tab->setPcId($a_pc_id);
816 return $tab;
817 }
818
819 // media extra handling (@todo: get rid of it)
820 if ($node_name == "MediaObject")
821 {
822 if ($_GET["pgEdMediaMode"] != "") {echo "ilPageObject::error media"; exit;}
823
824 //require_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
825 require_once("./Services/COPage/classes/class.ilPCMediaObject.php");
826
827 $mal_node =& $child_node->first_child();
828//echo "ilPageObject::getContentObject:nodename:".$mal_node->node_name().":<br>";
829 $id_arr = explode("_", $mal_node->get_attribute("OriginId"));
830 $mob_id = $id_arr[count($id_arr) - 1];
831
832 // allow deletion of non-existing media objects
833 if (!ilObject::_exists($mob_id) && in_array("delete", $_POST))
834 {
835 $mob_id = 0;
836 }
837
838 //$mob =& new ilObjMediaObject($mob_id);
839 $mob = new ilPCMediaObject($this);
840 $mob->readMediaObject($mob_id);
841
842 //$mob->setDom($this->dom);
843 $mob->setNode($cont_node);
844 $mob->setHierId($a_hier_id);
845 $mob->setPcId($a_pc_id);
846 return $mob;
847 }
848
849 //
850 // generic procedure
851 //
852
853 $pc_def = ilCOPagePCDef::getPCDefinitionByName($node_name);
854
855 // check if pc definition has been found
856 if (!is_array($pc_def))
857 {
858 include_once("./Services/COPage/exceptions/class.ilCOPageUnknownPCTypeException.php");
859 throw new ilCOPageUnknownPCTypeException('Unknown PC Name "'.$node_name.'".');
860 }
861 $pc_class = "ilPC".$pc_def["name"];
862 $pc_path = "./".$pc_def["component"]."/".$pc_def["directory"]."/class.".$pc_class.".php";
863 require_once($pc_path);
864 $pc = new $pc_class($this);
865 $pc->setNode($cont_node);
866 $pc->setHierId($a_hier_id);
867 $pc->setPcId($a_pc_id);
868 return $pc;
869 }
870
877 function &getContentNode($a_hier_id, $a_pc_id = "")
878 {
879 $xpc = xpath_new_context($this->dom);
880 if($a_hier_id == "pg")
881 {
882 return $this->node;
883 }
884 else
885 {
886 // get per pc id
887 if ($a_pc_id != "")
888 {
889 $path = "//*[@PCID = '$a_pc_id']";
890 $res =& xpath_eval($xpc, $path);
891 if (count($res->nodeset) == 1)
892 {
893 $cont_node =& $res->nodeset[0];
894 return $cont_node;
895 }
896 }
897
898 // fall back to hier id
899 $path = "//*[@HierId = '$a_hier_id']";
900 $res =& xpath_eval($xpc, $path);
901 if (count($res->nodeset) == 1)
902 {
903 $cont_node =& $res->nodeset[0];
904 return $cont_node;
905 }
906 }
907 }
908
915 function checkForTag($a_content_tag, $a_hier_id, $a_pc_id = "")
916 {
917 $xpc = xpath_new_context($this->dom);
918 // get per pc id
919 if ($a_pc_id != "")
920 {
921 $path = "//*[@PCID = '$a_pc_id']//".$a_content_tag;
922 $res = xpath_eval($xpc, $path);
923 if (count($res->nodeset) > 0)
924 {
925 return true;
926 }
927 }
928
929 // fall back to hier id
930 $path = "//*[@HierId = '$a_hier_id']//".$a_content_tag;
931 $res =& xpath_eval($xpc, $path);
932 if (count($res->nodeset) > 0)
933 {
934 return true;
935 }
936 return false;
937 }
938
939 // only for test purposes
940 function lookforhier($a_hier_id)
941 {
942 $xpc = xpath_new_context($this->dom);
943 $path = "//*[@HierId = '$a_hier_id']";
944 $res =& xpath_eval($xpc, $path);
945 if (count($res->nodeset) == 1)
946 return "YES";
947 else
948 return "NO";
949 }
950
951
952 function &getNode()
953 {
954 return $this->node;
955 }
956
957
966 function setXMLContent($a_xml, $a_encoding = "UTF-8")
967 {
968 $this->encoding = $a_encoding;
969 $this->xml = $a_xml;
970 }
971
978 function appendXMLContent($a_xml)
979 {
980 $this->xml.= $a_xml;
981 }
982
983
987 function getXMLContent($a_incl_head = false)
988 {
989 // build full http path for XML DOCTYPE header.
990 // Under windows a relative path doesn't work :-(
991 if($a_incl_head)
992 {
993//echo "+".$this->encoding."+";
994 $enc_str = (!empty($this->encoding))
995 ? "encoding=\"".$this->encoding."\""
996 : "";
997 return "<?xml version=\"1.0\" $enc_str ?>".
998 "<!DOCTYPE PageObject SYSTEM \"".ILIAS_ABSOLUTE_PATH."/xml/".$this->cur_dtd."\">".
999 $this->xml;
1000 }
1001 else
1002 {
1003 return $this->xml;
1004 }
1005 }
1006
1011 function copyXmlContent($a_clone_mobs = false)
1012 {
1013 $xml = $this->getXmlContent();
1014 $temp_dom = domxml_open_mem('<?xml version="1.0" encoding="UTF-8"?>'.$xml,
1015 DOMXML_LOAD_PARSING, $error);
1016 if(empty($error))
1017 {
1018 $this->handleCopiedContent($temp_dom, true, $a_clone_mobs);
1019 }
1020 $xml = $temp_dom->dump_mem(0, $this->encoding);
1021 $xml = eregi_replace("<\?xml[^>]*>","",$xml);
1022 $xml = eregi_replace("<!DOCTYPE[^>]*>","",$xml);
1023
1024 return $xml;
1025 }
1026
1027// @todo 1: begin: generalize, remove concrete dependencies
1028
1038 function handleCopiedContent($a_dom, $a_self_ass = true, $a_clone_mobs = false)
1039 {
1040 include_once("./Services/COPage/classes/class.ilCOPagePCDef.php");
1042
1043 // handle question elements
1044 if ($a_self_ass)
1045 {
1046 $this->newQuestionCopies($a_dom);
1047 }
1048 else
1049 {
1050 $this->removeQuestions($a_dom);
1051 }
1052
1053 // handle interactive images
1054 $this->newIIMCopies($a_dom);
1055
1056 // handle media objects
1057 if ($a_clone_mobs)
1058 {
1059 $this->newMobCopies($a_dom);
1060 }
1061
1062// @todo 1: move all functions from above to the new domdoc
1063 if ($a_dom instanceof php4DOMDocument)
1064 {
1065 $a_dom = $a_dom->myDOMDocument;
1066 }
1067 foreach ($defs as $def)
1068 {
1070 $cl = $def["pc_class"];
1071 $cl::handleCopiedContent($a_dom, $a_self_ass, $a_clone_mobs);
1072 }
1073
1074 }
1075
1080 function newIIMCopies($temp_dom)
1081 {
1082 // Get question IDs
1083 $path = "//InteractiveImage/MediaAlias";
1084 $xpc = xpath_new_context($temp_dom);
1085 $res = & xpath_eval($xpc, $path);
1086
1087 $q_ids = array();
1088 include_once("./Services/Link/classes/class.ilInternalLink.php");
1089 for ($i = 0; $i < count ($res->nodeset); $i++)
1090 {
1091 $or_id = $res->nodeset[$i]->get_attribute("OriginId");
1092
1093 $inst_id = ilInternalLink::_extractInstOfTarget($or_id);
1094 $mob_id = ilInternalLink::_extractObjIdOfTarget($or_id);
1095
1096 if (!($inst_id > 0))
1097 {
1098 if ($mob_id > 0)
1099 {
1100 include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
1101 $media_object = new ilObjMediaObject($mob_id);
1102
1103 // now copy this question and change reference to
1104 // new question id
1105 $new_mob = $media_object->duplicate();
1106
1107 $res->nodeset[$i]->set_attribute("OriginId", "il__mob_".$new_mob->getId());
1108 }
1109 }
1110 }
1111 }
1112
1116 function newMobCopies($temp_dom)
1117 {
1118 // Get question IDs
1119 $path = "//MediaObject/MediaAlias";
1120 $xpc = xpath_new_context($temp_dom);
1121 $res = & xpath_eval($xpc, $path);
1122
1123 $q_ids = array();
1124 include_once("./Services/Link/classes/class.ilInternalLink.php");
1125 for ($i = 0; $i < count ($res->nodeset); $i++)
1126 {
1127 $or_id = $res->nodeset[$i]->get_attribute("OriginId");
1128
1129 $inst_id = ilInternalLink::_extractInstOfTarget($or_id);
1130 $mob_id = ilInternalLink::_extractObjIdOfTarget($or_id);
1131
1132 if (!($inst_id > 0))
1133 {
1134 if ($mob_id > 0)
1135 {
1136 include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
1137 $media_object = new ilObjMediaObject($mob_id);
1138
1139 // now copy this question and change reference to
1140 // new question id
1141 $new_mob = $media_object->duplicate();
1142
1143 $res->nodeset[$i]->set_attribute("OriginId", "il__mob_".$new_mob->getId());
1144 }
1145 }
1146 }
1147 }
1148
1153 function newQuestionCopies(&$temp_dom)
1154 {
1155 // Get question IDs
1156 $path = "//Question";
1157 $xpc = xpath_new_context($temp_dom);
1158 $res = & xpath_eval($xpc, $path);
1159
1160 $q_ids = array();
1161 include_once("./Services/Link/classes/class.ilInternalLink.php");
1162 for ($i = 0; $i < count ($res->nodeset); $i++)
1163 {
1164 $qref = $res->nodeset[$i]->get_attribute("QRef");
1165
1166 $inst_id = ilInternalLink::_extractInstOfTarget($qref);
1168
1169 if (!($inst_id > 0))
1170 {
1171 if ($q_id > 0)
1172 {
1173 include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
1174 $question = assQuestion::_instantiateQuestion($q_id);
1175 // check due to #16557
1176 if (is_object($question) && $question->isComplete())
1177 {
1178 // check if page for question exists
1179 // due to a bug in early 4.2.x version this is possible
1180 if (!ilPageObject::_exists("qpl", $q_id))
1181 {
1182 $question->createPageObject();
1183 }
1184
1185 // now copy this question and change reference to
1186 // new question id
1187 $duplicate_id = $question->duplicate(false);
1188 $res->nodeset[$i]->set_attribute("QRef", "il__qst_".$duplicate_id);
1189 }
1190 }
1191 }
1192 }
1193 }
1194
1201 function removeQuestions(&$temp_dom)
1202 {
1203 // Get question IDs
1204 $path = "//Question";
1205 $xpc = xpath_new_context($temp_dom);
1206 $res = & xpath_eval($xpc, $path);
1207 for ($i = 0; $i < count ($res->nodeset); $i++)
1208 {
1209 $parent_node = $res->nodeset[$i]->parent_node();
1210 $parent_node->unlink_node($parent_node);
1211 }
1212 }
1213
1214// @todo: end
1215
1223 {
1224 // Get question IDs
1225 $this->buildDom();
1226 $path = "//PageContent";
1227 $xpc = xpath_new_context($this->dom);
1228 $res = & xpath_eval($xpc, $path);
1229 return count ($res->nodeset);
1230 }
1231
1236 function getXMLFromDom($a_incl_head = false, $a_append_mobs = false, $a_append_bib = false,
1237 $a_append_str = "", $a_omit_pageobject_tag = false)
1238 {
1239 if ($a_incl_head)
1240 {
1241//echo "\n<br>#".$this->encoding."#";
1242 return $this->dom->dump_mem(0, $this->encoding);
1243 }
1244 else
1245 {
1246 // append multimedia object elements
1247 if ($a_append_mobs || $a_append_bib || $a_append_link_info)
1248 {
1249 $mobs = "";
1250 $bibs = "";
1251 if ($a_append_mobs)
1252 {
1253 $mobs =& $this->getMultimediaXML();
1254 }
1255 if ($a_append_bib)
1256 {
1257// deprecated
1258// $bibs =& $this->getBibliographyXML();
1259 }
1260 $trans =& $this->getLanguageVariablesXML();
1261 return "<dummy>".$this->dom->dump_node($this->node).$mobs.$bibs.$trans.$a_append_str."</dummy>";
1262 }
1263 else
1264 {
1265 if (is_object($this->dom))
1266 {
1267 if ($a_omit_pageobject_tag)
1268 {
1269 $xml = "";
1270 $childs =& $this->node->child_nodes();
1271 for($i = 0; $i < count($childs); $i++)
1272 {
1273 $xml.= $this->dom->dump_node($childs[$i]);
1274 }
1275 return $xml;
1276 }
1277 else
1278 {
1279 $xml = $this->dom->dump_mem(0, $this->encoding);
1280 $xml = eregi_replace("<\?xml[^>]*>","",$xml);
1281 $xml = eregi_replace("<!DOCTYPE[^>]*>","",$xml);
1282
1283 return $xml;
1284
1285 // don't use dump_node. This gives always entities.
1286 //return $this->dom->dump_node($this->node);
1287 }
1288 }
1289 else
1290 {
1291 return "";
1292 }
1293 }
1294 }
1295 }
1296
1301 {
1302 global $lng;
1303
1304 $xml = "<LVs>";
1305 $lang_vars = array(
1306 "ed_paste_clip", "ed_edit", "ed_edit_prop", "ed_delete", "ed_moveafter",
1307 "ed_movebefore", "ed_go", "ed_class", "ed_width", "ed_align_left",
1308 "ed_align_right", "ed_align_center", "ed_align_left_float",
1309 "ed_align_right_float", "ed_delete_item", "ed_new_item_before",
1310 "ed_new_item_after", "ed_copy_clip", "please_select", "ed_split_page",
1311 "ed_item_up", "ed_item_down", "ed_split_page_next","ed_enable",
1312 "de_activate", "ed_paste", "ed_edit_multiple", "ed_cut", "ed_copy", "ed_insert_templ",
1313 "ed_click_to_add_pg", "download");
1314
1315 // collect lang vars from pc elements
1316 include_once("./Services/COPage/classes/class.ilCOPagePCDef.php");
1318 foreach ($defs as $def)
1319 {
1320 $lang_vars[] = "pc_".$def["pc_type"];
1321 $lang_vars[] = "ed_insert_".$def["pc_type"];
1322
1324 $cl = $def["pc_class"];
1325 $lvs = call_user_func($def["pc_class"].'::getLangVars');
1326 foreach ($lvs as $lv)
1327 {
1328 $lang_vars[] = $lv;
1329 }
1330 }
1331
1332 foreach ($lang_vars as $lang_var)
1333 {
1334 $this->appendLangVarXML($xml, $lang_var);
1335 }
1336
1337 $xml.= "</LVs>";
1338
1339 return $xml;
1340 }
1341
1342 function appendLangVarXML(&$xml, $var)
1343 {
1344 global $lng;
1345
1346 $xml.= "<LV name=\"$var\" value=\"".$lng->txt("cont_".$var)."\"/>";
1347 }
1348
1349// @todo begin: move this to paragraph class
1350
1352 {
1353 if($this->dom)
1354 {
1355 require_once("./Services/COPage/classes/class.ilPCParagraph.php");
1356 $xpc = xpath_new_context($this->dom);
1357 $path = "//Paragraph[1]";
1358 $res =& xpath_eval($xpc, $path);
1359 if (count($res->nodeset) > 0)
1360 {
1361 $cont_node =& $res->nodeset[0]->parent_node();
1362 $par =& new ilPCParagraph($this);
1363 $par->setNode($cont_node);
1364 return $par->getText();
1365 }
1366 }
1367 return "";
1368 }
1369
1376 function setParagraphContent($a_hier_id, $a_content)
1377 {
1378 $node = $this->getContentNode($a_hier_id);
1379 if (is_object($node))
1380 {
1381 $node->set_content($a_content);
1382 }
1383 }
1384
1385// @todo end
1386
1387
1396 // @todo: can we do this better
1397 function setContainsIntLink($a_contains_link)
1398 {
1399 $this->contains_int_link = $a_contains_link;
1400 }
1401
1406 // @todo: can we do this better
1408 {
1410 }
1411
1417 function setImportMode($a_val)
1418 {
1419 $this->import_mode = $a_val;
1420 }
1421
1427 function getImportMode()
1428 {
1429 return $this->import_mode;
1430 }
1431
1432 function needsImportParsing($a_parse = "")
1433 {
1434
1435 if ($a_parse === true)
1436 {
1437 $this->needs_parsing = true;
1438 }
1439 if ($a_parse === false)
1440 {
1441 $this->needs_parsing = false;
1442 }
1443 return $this->needs_parsing;
1444 }
1445
1451 // @todo: can we do this better
1452 public function setContainsQuestion($a_val)
1453 {
1454 $this->contains_question = $a_val;
1455 }
1456
1462 public function getContainsQuestion()
1463 {
1464 return $this->contains_question;
1465 }
1466
1467
1472 // @todo: move to media class
1473 function collectMediaObjects($a_inline_only = true)
1474 {
1475//echo htmlentities($this->getXMLFromDom());
1476 // determine all media aliases of the page
1477 $xpc = xpath_new_context($this->dom);
1478 $path = "//MediaObject/MediaAlias";
1479 $res =& xpath_eval($xpc, $path);
1480 $mob_ids = array();
1481 for($i = 0; $i < count($res->nodeset); $i++)
1482 {
1483 $id_arr = explode("_", $res->nodeset[$i]->get_attribute("OriginId"));
1484 $mob_id = $id_arr[count($id_arr) - 1];
1485 $mob_ids[$mob_id] = $mob_id;
1486 }
1487
1488 // determine all media aliases of interactive images
1489 $xpc = xpath_new_context($this->dom);
1490 $path = "//InteractiveImage/MediaAlias";
1491 $res =& xpath_eval($xpc, $path);
1492 for($i = 0; $i < count($res->nodeset); $i++)
1493 {
1494 $id_arr = explode("_", $res->nodeset[$i]->get_attribute("OriginId"));
1495 $mob_id = $id_arr[count($id_arr) - 1];
1496 $mob_ids[$mob_id] = $mob_id;
1497 }
1498
1499 // determine all inline internal media links
1500 $xpc = xpath_new_context($this->dom);
1501 $path = "//IntLink[@Type = 'MediaObject']";
1502 $res =& xpath_eval($xpc, $path);
1503
1504 for($i = 0; $i < count($res->nodeset); $i++)
1505 {
1506 if (($res->nodeset[$i]->get_attribute("TargetFrame") == "") ||
1507 (!$a_inline_only))
1508 {
1509 $target = $res->nodeset[$i]->get_attribute("Target");
1510 $id_arr = explode("_", $target);
1511 if (($id_arr[1] == IL_INST_ID) ||
1512 (substr($target, 0, 4) == "il__"))
1513 {
1514 $mob_id = $id_arr[count($id_arr) - 1];
1515 if (ilObject::_exists($mob_id))
1516 {
1517 $mob_ids[$mob_id] = $mob_id;
1518 }
1519 }
1520 }
1521 }
1522
1523 return $mob_ids;
1524 }
1525
1526
1530 // @todo: can we do this better?
1531 function getInternalLinks($a_cnt_multiple = false)
1532 {
1533 // get all internal links of the page
1534 $xpc = xpath_new_context($this->dom);
1535 $path = "//IntLink";
1536 $res = xpath_eval($xpc, $path);
1537
1538 $links = array();
1539 $cnt_multiple = 1;
1540 for($i = 0; $i < count($res->nodeset); $i++)
1541 {
1542 $add = "";
1543 if ($a_cnt_multiple)
1544 {
1545 $add = ":".$cnt_multiple;
1546 }
1547 $target = $res->nodeset[$i]->get_attribute("Target");
1548 $type = $res->nodeset[$i]->get_attribute("Type");
1549 $targetframe = $res->nodeset[$i]->get_attribute("TargetFrame");
1550 $anchor = $res->nodeset[$i]->get_attribute("Anchor");
1551 $links[$target.":".$type.":".$targetframe.":".$anchor.$add] =
1552 array("Target" => $target, "Type" => $type,
1553 "TargetFrame" => $targetframe, "Anchor" => $anchor);
1554
1555 // get links (image map areas) for inline media objects
1556 if ($type == "MediaObject" && $targetframe == "")
1557 {
1558 if (substr($target, 0, 4) =="il__")
1559 {
1560 $id_arr = explode("_", $target);
1561 $id = $id_arr[count($id_arr) - 1];
1562
1564 foreach($med_links as $key => $med_link)
1565 {
1566 $links[$key] = $med_link;
1567 }
1568 }
1569
1570 }
1571//echo "<br>-:".$target.":".$type.":".$targetframe.":-";
1572 $cnt_multiple++;
1573 }
1574 unset($xpc);
1575
1576 // get all media aliases
1577 $xpc = xpath_new_context($this->dom);
1578 $path = "//MediaAlias";
1579 $res =& xpath_eval($xpc, $path);
1580
1581 require_once("Services/MediaObjects/classes/class.ilMediaItem.php");
1582 for($i = 0; $i < count($res->nodeset); $i++)
1583 {
1584 $oid = $res->nodeset[$i]->get_attribute("OriginId");
1585 if (substr($oid, 0, 4) =="il__")
1586 {
1587 $id_arr = explode("_", $oid);
1588 $id = $id_arr[count($id_arr) - 1];
1589
1591 foreach($med_links as $key => $med_link)
1592 {
1593 $links[$key] = $med_link;
1594 }
1595 }
1596 }
1597 unset($xpc);
1598
1599 return $links;
1600 }
1601
1606 // @todo: move to media class
1608 {
1609 $mob_ids = $this->collectMediaObjects();
1610
1611 // get xml of corresponding media objects
1612 $mobs_xml = "";
1613 require_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
1614 foreach($mob_ids as $mob_id => $dummy)
1615 {
1616 if (ilObject::_lookupType($mob_id) == "mob")
1617 {
1618 $mob_obj =& new ilObjMediaObject($mob_id);
1619 $mobs_xml .= $mob_obj->getXML(IL_MODE_OUTPUT);
1620 }
1621 }
1622//var_dump($mobs_xml);
1623 return $mobs_xml;
1624 }
1625
1629 // @todo: move to media class
1630 function getMediaAliasElement($a_mob_id, $a_nr = 1)
1631 {
1632 $xpc = xpath_new_context($this->dom);
1633 $path = "//MediaObject/MediaAlias[@OriginId='il__mob_$a_mob_id']";
1634 $res =& xpath_eval($xpc, $path);
1635 $mal_node =& $res->nodeset[$a_nr - 1];
1636 $mob_node =& $mal_node->parent_node();
1637
1638 return $this->dom->dump_node($mob_node);
1639 }
1640
1646 function validateDom()
1647 {
1648 $this->stripHierIDs();
1649
1650 // possible fix for #14820
1651 libxml_disable_entity_loader(false);
1652
1653 @$this->dom->validate($error);
1654
1655 return $error;
1656 }
1657
1673 // @todo: can we do this better? remove dependencies?
1674 function addHierIDs()
1675 {
1676 $this->hier_ids = array();
1677 $this->first_row_ids = array();
1678 $this->first_col_ids = array();
1679 $this->list_item_ids = array();
1680 $this->file_item_ids = array();
1681
1682 // set hierarchical ids for Paragraphs, Tables, TableRows and TableData elements
1683 $xpc = xpath_new_context($this->dom);
1684 //$path = "//Paragraph | //Table | //TableRow | //TableData";
1685
1686 $sep = $path = "";
1687 foreach ($this->id_elements as $el)
1688 {
1689 $path.= $sep."//".$el;
1690 $sep = " | ";
1691 }
1692
1693 $res =& xpath_eval($xpc, $path);
1694 for($i = 0; $i < count($res->nodeset); $i++)
1695 {
1696 $cnode = $res->nodeset[$i];
1697 $ctag = $cnode->node_name();
1698
1699 // get hierarchical id of previous sibling
1700 $sib_hier_id = "";
1701 while($cnode =& $cnode->previous_sibling())
1702 {
1703 if (($cnode->node_type() == XML_ELEMENT_NODE)
1704 && $cnode->has_attribute("HierId"))
1705 {
1706 $sib_hier_id = $cnode->get_attribute("HierId");
1707 //$sib_hier_id = $id_attr->value();
1708 break;
1709 }
1710 }
1711
1712 if ($sib_hier_id != "") // set id to sibling id "+ 1"
1713 {
1714 require_once("./Services/COPage/classes/class.ilPageContent.php");
1715 $node_hier_id = ilPageContent::incEdId($sib_hier_id);
1716 $res->nodeset[$i]->set_attribute("HierId", $node_hier_id);
1717 $this->hier_ids[] = $node_hier_id;
1718 if ($ctag == "TableData")
1719 {
1720 if (substr($par_hier_id,strlen($par_hier_id)-2) == "_1")
1721 {
1722 $this->first_row_ids[] = $node_hier_id;
1723 }
1724 }
1725 if ($ctag == "ListItem")
1726 {
1727 $this->list_item_ids[] = $node_hier_id;
1728 }
1729 if ($ctag == "FileItem")
1730 {
1731 $this->file_item_ids[] = $node_hier_id;
1732 }
1733 }
1734 else // no sibling -> node is first child
1735 {
1736 // get hierarchical id of next parent
1737 $cnode = $res->nodeset[$i];
1738 $par_hier_id = "";
1739 while($cnode =& $cnode->parent_node())
1740 {
1741 if (($cnode->node_type() == XML_ELEMENT_NODE)
1742 && $cnode->has_attribute("HierId"))
1743 {
1744 $par_hier_id = $cnode->get_attribute("HierId");
1745 //$par_hier_id = $id_attr->value();
1746 break;
1747 }
1748 }
1749//echo "<br>par:".$par_hier_id." ($ctag)";
1750 if (($par_hier_id != "") && ($par_hier_id != "pg")) // set id to parent_id."_1"
1751 {
1752 $node_hier_id = $par_hier_id."_1";
1753 $res->nodeset[$i]->set_attribute("HierId", $node_hier_id);
1754 $this->hier_ids[] = $node_hier_id;
1755 if ($ctag == "TableData")
1756 {
1757 $this->first_col_ids[] = $node_hier_id;
1758 if (substr($par_hier_id,strlen($par_hier_id)-2) == "_1")
1759 {
1760 $this->first_row_ids[] = $node_hier_id;
1761 }
1762 }
1763 if ($ctag == "ListItem")
1764 {
1765 $this->list_item_ids[] = $node_hier_id;
1766 }
1767 if ($ctag == "FileItem")
1768 {
1769 $this->file_item_ids[] = $node_hier_id;
1770 }
1771
1772 }
1773 else // no sibling, no parent -> first node
1774 {
1775 $node_hier_id = "1";
1776 $res->nodeset[$i]->set_attribute("HierId", $node_hier_id);
1777 $this->hier_ids[] = $node_hier_id;
1778 }
1779 }
1780 }
1781
1782 // set special hierarchical id "pg" for pageobject
1783 $xpc = xpath_new_context($this->dom);
1784 $path = "//PageObject";
1785 $res =& xpath_eval($xpc, $path);
1786 for($i = 0; $i < count($res->nodeset); $i++) // should only be 1
1787 {
1788 $res->nodeset[$i]->set_attribute("HierId", "pg");
1789 $this->hier_ids[] = "pg";
1790 }
1791 unset($xpc);
1792 }
1793
1797 function getHierIds()
1798 {
1799 return $this->hier_ids;
1800 }
1801
1805 // @todo: move to table classes
1807 {
1808 return $this->first_row_ids;
1809 }
1810
1814 // @todo: move to table classes
1816 {
1817 return $this->first_col_ids;
1818 }
1819
1823 // @todo: move to list class
1825 {
1826 return $this->list_item_ids;
1827 }
1828
1832 // @todo: move to file item class
1834 {
1835 return $this->file_item_ids;
1836 }
1837
1841 function stripHierIDs()
1842 {
1843 if(is_object($this->dom))
1844 {
1845 $xpc = xpath_new_context($this->dom);
1846 $path = "//*[@HierId]";
1847 $res =& xpath_eval($xpc, $path);
1848 for($i = 0; $i < count($res->nodeset); $i++) // should only be 1
1849 {
1850 if ($res->nodeset[$i]->has_attribute("HierId"))
1851 {
1852 $res->nodeset[$i]->remove_attribute("HierId");
1853 }
1854 }
1855 unset($xpc);
1856 }
1857 }
1858
1862 function getHierIdsForPCIds($a_pc_ids)
1863 {
1864 if (!is_array($a_pc_ids) || count($a_pc_ids) == 0)
1865 {
1866 return array();
1867 }
1868 $ret = array();
1869
1870 if(is_object($this->dom))
1871 {
1872 $xpc = xpath_new_context($this->dom);
1873 $path = "//*[@PCID]";
1874 $res =& xpath_eval($xpc, $path);
1875 for($i = 0; $i < count($res->nodeset); $i++) // should only be 1
1876 {
1877 $pc_id = $res->nodeset[$i]->get_attribute("PCID");
1878 if (in_array($pc_id, $a_pc_ids))
1879 {
1880 $ret[$pc_id] = $res->nodeset[$i]->get_attribute("HierId");
1881 }
1882 }
1883 unset($xpc);
1884 }
1885//var_dump($ret);
1886 return $ret;
1887 }
1888
1892 // @todo: move to file item class
1893 function addFileSizes()
1894 {
1895 $xpc = xpath_new_context($this->dom);
1896 $path = "//FileItem";
1897 $res =& xpath_eval($xpc, $path);
1898 for($i = 0; $i < count($res->nodeset); $i++)
1899 {
1900 $cnode =& $res->nodeset[$i];
1901 $size_node =& $this->dom->create_element("Size");
1902 $size_node =& $cnode->append_child($size_node);
1903
1904 $childs =& $cnode->child_nodes();
1905 $size = "";
1906 for($j = 0; $j < count($childs); $j++)
1907 {
1908 if ($childs[$j]->node_name() == "Identifier")
1909 {
1910 if ($childs[$j]->has_attribute("Entry"))
1911 {
1912 $entry = $childs[$j]->get_attribute("Entry");
1913 $entry_arr = explode("_", $entry);
1914 $id = $entry_arr[count($entry_arr) - 1];
1915 require_once("./Modules/File/classes/class.ilObjFile.php");
1917 }
1918 }
1919 }
1920 $size_node->set_content($size);
1921 }
1922
1923 unset($xpc);
1924 }
1925
1930 // @todo: possible to improve this?
1931 function resolveIntLinks($a_link_map = null)
1932 {
1933 $changed = false;
1934
1935 $this->log->debug("start");
1936
1937 // resolve normal internal links
1938 $xpc = xpath_new_context($this->dom);
1939 $path = "//IntLink";
1940 $res =& xpath_eval($xpc, $path);
1941 for($i = 0; $i < count($res->nodeset); $i++)
1942 {
1943 $target = $res->nodeset[$i]->get_attribute("Target");
1944 $type = $res->nodeset[$i]->get_attribute("Type");
1945
1946 if ($a_link_map == null)
1947 {
1948 $new_target = ilInternalLink::_getIdForImportId($type, $target);
1949 $this->log->debug("no map, type: ".$type.", target: ".$target.", new target: ".$new_target);
1950// echo "-".$new_target."-".$type."-".$target."-"; exit;
1951 }
1952 else
1953 {
1954 $nt = explode("_", $a_link_map[$target]);
1955 $new_target = false;
1956 if ($nt[1] == IL_INST_ID)
1957 {
1958 $new_target = "il__".$nt[2]."_".$nt[3];
1959 }
1960 $this->log->debug("map, type: ".$type.", target: ".$target.", new target: ".$new_target);
1961 }
1962 if ($new_target !== false)
1963 {
1964 $res->nodeset[$i]->set_attribute("Target", $new_target);
1965 $changed = true;
1966 }
1967 else // check wether link target is same installation
1968 {
1969 if (ilInternalLink::_extractInstOfTarget($target) == IL_INST_ID &&
1970 IL_INST_ID > 0 && $type != "RepositoryItem")
1971 {
1972 $new_target = ilInternalLink::_removeInstFromTarget($target);
1973 if (ilInternalLink::_exists($type, $new_target))
1974 {
1975 $res->nodeset[$i]->set_attribute("Target", $new_target);
1976 $changed = true;
1977 }
1978 }
1979 }
1980
1981 }
1982 unset($xpc);
1983
1984 // resolve internal links in map areas
1985 $xpc = xpath_new_context($this->dom);
1986 $path = "//MediaAlias";
1987 $res =& xpath_eval($xpc, $path);
1988//echo "<br><b>page::resolve</b><br>";
1989//echo "Content:".htmlentities($this->getXMLFromDOM()).":<br>";
1990 for($i = 0; $i < count($res->nodeset); $i++)
1991 {
1992 $orig_id = $res->nodeset[$i]->get_attribute("OriginId");
1993 $id_arr = explode("_", $orig_id);
1994 $mob_id = $id_arr[count($id_arr) - 1];
1996 }
1997 return $changed;
1998 }
1999
2006 // @todo: move to media classes?
2007 function resolveMediaAliases($a_mapping, $a_reuse_existing_by_import = false)
2008 {
2009 // resolve normal internal links
2010 $xpc = xpath_new_context($this->dom);
2011 $path = "//MediaAlias";
2012 $res =& xpath_eval($xpc, $path);
2013 $changed = false;
2014 for($i = 0; $i < count($res->nodeset); $i++)
2015 {
2016 // get the ID of the import file from the xml
2017 $old_id = $res->nodeset[$i]->get_attribute("OriginId");
2018 $old_id = explode("_", $old_id);
2019 $old_id = $old_id[count($old_id) - 1];
2020 // get the new id from the current mapping
2021 if ($a_mapping[$old_id] > 0)
2022 {
2023 $new_id = $a_mapping[$old_id];
2024 if ($a_reuse_existing_by_import)
2025 {
2026 // this should work, if the lm has been imported in a translation installation and re-exported
2027 $import_id = ilObject::_lookupImportId($new_id);
2028 $imp = explode("_", $import_id);
2029 if ($imp[1] == IL_INST_ID && $imp[2] == "mob" && ilObject::_lookupType($imp[3]) == "mob")
2030 {
2031 $new_id = $imp[3];
2032 }
2033
2034 // now check, if the translation has been done just by changing text in the exported
2035 // translation file
2036 if ($import_id == "")
2037 {
2038 // if the old_id is also referred by the page content of the default language
2039 // we assume that this media object is unchanged
2040 include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
2041 $med_of_def_lang = ilObjMediaObject::_getMobsOfObject("lm:pg", $this->getId(), 0, "-");
2042 if (in_array($old_id, $med_of_def_lang))
2043 {
2044 $new_id = $old_id;
2045 }
2046 }
2047 }
2048
2049 $res->nodeset[$i]->set_attribute("OriginId", "il__mob_".$new_id);
2050 $changed = true;
2051 }
2052 }
2053 unset($xpc);
2054
2055 return $changed;
2056 }
2057
2064 // @todo: move to iim classes?
2065 function resolveIIMMediaAliases($a_mapping)
2066 {
2067 // resolve normal internal links
2068 $xpc = xpath_new_context($this->dom);
2069 $path = "//InteractiveImage/MediaAlias";
2070 $res =& xpath_eval($xpc, $path);
2071 $changed = false;
2072 for($i = 0; $i < count($res->nodeset); $i++)
2073 {
2074 $old_id = $res->nodeset[$i]->get_attribute("OriginId");
2075 if ($a_mapping[$old_id] > 0)
2076 {
2077 $res->nodeset[$i]->set_attribute("OriginId", "il__mob_".$a_mapping[$old_id]);
2078 $changed = true;
2079 }
2080 }
2081 unset($xpc);
2082
2083 return $changed;
2084 }
2085
2092 // @todo: move to file classes?
2093 function resolveFileItems($a_mapping)
2094 {
2095 // resolve normal internal links
2096 $xpc = xpath_new_context($this->dom);
2097 $path = "//FileItem/Identifier";
2098 $res =& xpath_eval($xpc, $path);
2099 $changed = false;
2100 for($i = 0; $i < count($res->nodeset); $i++)
2101 {
2102 $old_id = $res->nodeset[$i]->get_attribute("Entry");
2103 $old_id = explode("_", $old_id);
2104 $old_id = $old_id[count($old_id) - 1];
2105 if ($a_mapping[$old_id] > 0)
2106 {
2107 $res->nodeset[$i]->set_attribute("Entry", "il__file_".$a_mapping[$old_id]);
2108 $changed = true;
2109 }
2110 }
2111 unset($xpc);
2112
2113 return $changed;
2114 }
2115
2120 // @todo: move to question classes
2121 function resolveQuestionReferences($a_mapping)
2122 {
2123 // resolve normal internal links
2124 $xpc = xpath_new_context($this->dom);
2125 $path = "//Question";
2126 $res =& xpath_eval($xpc, $path);
2127 $updated = false;
2128 for($i = 0; $i < count($res->nodeset); $i++)
2129 {
2130 $qref = $res->nodeset[$i]->get_attribute("QRef");
2131
2132 if (isset($a_mapping[$qref]))
2133 {
2134 $res->nodeset[$i]->set_attribute("QRef", "il__qst_".$a_mapping[$qref]["pool"]);
2135 $updated = true;
2136 }
2137 }
2138 unset($xpc);
2139
2140 return $updated;
2141 }
2142
2143
2150 // @todo: generalize, internal links usage info
2151 function moveIntLinks($a_from_to)
2152 {
2153 $this->buildDom();
2154
2155 $changed = false;
2156
2157 // resolve normal internal links
2158 $xpc = xpath_new_context($this->dom);
2159 $path = "//IntLink";
2160 $res =& xpath_eval($xpc, $path);
2161 for($i = 0; $i < count($res->nodeset); $i++)
2162 {
2163 $target = $res->nodeset[$i]->get_attribute("Target");
2164 $type = $res->nodeset[$i]->get_attribute("Type");
2165 $obj_id = ilInternalLink::_extractObjIdOfTarget($target);
2166 if ($a_from_to[$obj_id] > 0 && is_int(strpos($target, "__")))
2167 {
2168 if ($type == "PageObject" && ilLMObject::_lookupType($a_from_to[$obj_id]) == "pg")
2169 {
2170 $res->nodeset[$i]->set_attribute("Target", "il__pg_".$a_from_to[$obj_id]);
2171 $changed = true;
2172 }
2173 if ($type == "StructureObject" && ilLMObject::_lookupType($a_from_to[$obj_id]) == "st")
2174 {
2175 $res->nodeset[$i]->set_attribute("Target", "il__st_".$a_from_to[$obj_id]);
2176 $changed = true;
2177 }
2178 }
2179 }
2180 unset($xpc);
2181
2182 // map areas
2183 $this->addHierIDs();
2184 $xpc = xpath_new_context($this->dom);
2185 $path = "//MediaAlias";
2186 $res =& xpath_eval($xpc, $path);
2187
2188 require_once("Services/MediaObjects/classes/class.ilMediaItem.php");
2189 require_once("Services/COPage/classes/class.ilMediaAliasItem.php");
2190
2191 for($i = 0; $i < count($res->nodeset); $i++)
2192 {
2193 $media_object_node = $res->nodeset[$i]->parent_node();
2194 $page_content_node = $media_object_node->parent_node();
2195 $c_hier_id = $page_content_node->get_attribute("HierId");
2196
2197 // first check, wheter we got instance map areas -> take these
2198 $std_alias_item = new ilMediaAliasItem($this->dom,
2199 $c_hier_id, "Standard");
2200 $areas = $std_alias_item->getMapAreas();
2201 $correction_needed = false;
2202 if (count($areas) > 0)
2203 {
2204 // check if correction needed
2205 foreach($areas as $area)
2206 {
2207 if ($area["Type"] == "PageObject" ||
2208 $area["Type"] == "StructureObject")
2209 {
2210 $t = $area["Target"];
2211 $tid = _extractObjIdOfTarget($t);
2212 if ($a_from_to[$tid] > 0)
2213 {
2214 $correction_needed = true;
2215 }
2216 }
2217 }
2218 }
2219 else
2220 {
2221 $areas = array();
2222
2223 // get object map areas and check whether at least one must
2224 // be corrected
2225 $oid = $res->nodeset[$i]->get_attribute("OriginId");
2226 if (substr($oid, 0, 4) =="il__")
2227 {
2228 $id_arr = explode("_", $oid);
2229 $id = $id_arr[count($id_arr) - 1];
2230
2231 $mob = new ilObjMediaObject($id);
2232 $med_item = $mob->getMediaItem("Standard");
2233 $med_areas = $med_item->getMapAreas();
2234
2235 foreach($med_areas as $area)
2236 {
2237 $link_type = ($area->getLinkType() == "int")
2238 ? "IntLink"
2239 : "ExtLink";
2240
2241 $areas[] = array(
2242 "Nr" => $area->getNr(),
2243 "Shape" => $area->getShape(),
2244 "Coords" => $area->getCoords(),
2245 "Link" => array(
2246 "LinkType" => $link_type,
2247 "Href" => $area->getHref(),
2248 "Title" => $area->getTitle(),
2249 "Target" => $area->getTarget(),
2250 "Type" => $area->getType(),
2251 "TargetFrame" => $area->getTargetFrame()
2252 )
2253 );
2254
2255 if ($area->getType() == "PageObject" ||
2256 $area->getType() == "StructureObject")
2257 {
2258 $t = $area->getTarget();
2260 if ($a_from_to[$tid] > 0)
2261 {
2262 $correction_needed = true;
2263 }
2264//var_dump($a_from_to);
2265 }
2266 }
2267 }
2268 }
2269
2270 // correct map area links
2271 if ($correction_needed)
2272 {
2273 $changed = true;
2274 $std_alias_item->deleteAllMapAreas();
2275 foreach($areas as $area)
2276 {
2277 if ($area["Link"]["LinkType"] == "IntLink")
2278 {
2279 $target = $area["Link"]["Target"];
2280 $type = $area["Link"]["Type"];
2281 $obj_id = ilInternalLink::_extractObjIdOfTarget($target);
2282 if ($a_from_to[$obj_id] > 0)
2283 {
2284 if ($type == "PageObject" && ilLMObject::_lookupType($a_from_to[$obj_id]) == "pg")
2285 {
2286 $area["Link"]["Target"] = "il__pg_".$a_from_to[$obj_id];
2287 }
2288 if ($type == "StructureObject" && ilLMObject::_lookupType($a_from_to[$obj_id]) == "st")
2289 {
2290 $area["Link"]["Target"] = "il__st_".$a_from_to[$obj_id];
2291 }
2292 }
2293 }
2294
2295 $std_alias_item->addMapArea($area["Shape"], $area["Coords"],
2296 $area["Link"]["Title"],
2297 array( "Type" => $area["Link"]["Type"],
2298 "TargetFrame" => $area["Link"]["TargetFrame"],
2299 "Target" => $area["Link"]["Target"],
2300 "Href" => $area["Link"]["Href"],
2301 "LinkType" => $area["Link"]["LinkType"],
2302 ));
2303 }
2304 }
2305 }
2306 unset($xpc);
2307
2308 return $changed;
2309 }
2310
2316 // @todo: generalize, internal links usage info
2317 static function _handleImportRepositoryLinks($a_rep_import_id, $a_rep_type, $a_rep_ref_id)
2318 {
2319 include_once("./Services/Link/classes/class.ilInternalLink.php");
2320
2321//echo "-".$a_rep_import_id."-".$a_rep_ref_id."-";
2322 $sources = ilInternalLink::_getSourcesOfTarget("obj",
2323 ilInternalLink::_extractObjIdOfTarget($a_rep_import_id),
2324 ilInternalLink::_extractInstOfTarget($a_rep_import_id));
2325//var_dump($sources);
2326 foreach($sources as $source)
2327 {
2328//echo "A";
2329 if ($source["type"] == "lm:pg")
2330 {
2331//echo "B";
2332 include_once("./Modules/LearningModule/classes/class.ilLMPage.php");
2333 if (self::_exists("lm", $source["id"], $source["lang"]))
2334 {
2335 $page_obj = new ilLMPage($source["id"], 0, $source["lang"]);
2336 if (!$page_obj->page_not_found)
2337 {
2338 //echo "C";
2339 $page_obj->handleImportRepositoryLink($a_rep_import_id,
2340 $a_rep_type, $a_rep_ref_id);
2341 }
2342 $page_obj->update();
2343 }
2344 }
2345 }
2346 }
2347
2348 // @todo: generalize, internal links usage info
2349 function handleImportRepositoryLink($a_rep_import_id, $a_rep_type, $a_rep_ref_id)
2350 {
2351 $this->buildDom();
2352
2353 // resolve normal internal links
2354 $xpc = xpath_new_context($this->dom);
2355 $path = "//IntLink";
2356 $res =& xpath_eval($xpc, $path);
2357//echo "1";
2358 for($i = 0; $i < count($res->nodeset); $i++)
2359 {
2360//echo "2";
2361 $target = $res->nodeset[$i]->get_attribute("Target");
2362 $type = $res->nodeset[$i]->get_attribute("Type");
2363 if ($target == $a_rep_import_id && $type == "RepositoryItem")
2364 {
2365//echo "setting:"."il__".$a_rep_type."_".$a_rep_ref_id;
2366 $res->nodeset[$i]->set_attribute("Target",
2367 "il__".$a_rep_type."_".$a_rep_ref_id);
2368 }
2369 }
2370 unset($xpc);
2371 }
2372
2376 function createFromXML()
2377 {
2378 global $lng, $ilDB, $ilUser;
2379
2380//echo "<br>PageObject::createFromXML[".$this->getId()."]";
2381
2382 $empty = false;
2383 if($this->getXMLContent() == "")
2384 {
2385 $this->setXMLContent("<PageObject></PageObject>");
2386 $empty = true;
2387 }
2388
2389 $content = $this->getXMLContent();
2390 $this->buildDom(true);
2391 $dom_doc = $this->getDomDoc();
2392
2393 $iel = $this->containsDeactivatedElements($content);
2394 $inl = $this->containsIntLinks($content);
2395
2396 // create object
2397 $ilDB->insert("page_object", array(
2398 "page_id" => array("integer", $this->getId()),
2399 "parent_id" => array("integer", $this->getParentId()),
2400 "lang" => array("text", $this->getLanguage()),
2401 "content" => array("clob", $content),
2402 "parent_type" => array("text", $this->getParentType()),
2403 "create_user" => array("integer", $ilUser->getId()),
2404 "last_change_user" => array("integer", $ilUser->getId()),
2405 "active" => array("integer", (int) $this->getActive()),
2406 "activation_start" => array("timestamp", $this->getActivationStart()),
2407 "activation_end" => array("timestamp", $this->getActivationEnd()),
2408 "show_activation_info" => array("integer", (int) $this->getShowActivationInfo()),
2409 "inactive_elements" => array("integer", $iel),
2410 "int_links" => array("integer", $inl),
2411 "created" => array("timestamp", ilUtil::now()),
2412 "last_change" => array("timestamp", ilUtil::now())
2413 ));
2414
2415 // after update event
2416 $this->__afterUpdate($dom_doc, $content, true, $empty);
2417
2418 }
2419
2420
2429 function updateFromXML()
2430 {
2431 global $lng, $ilDB, $ilUser;
2432
2433 $this->log->debug("ilPageObject, updateFromXML(): start, id: ".$this->getId());
2434
2435//echo "<br>PageObject::updateFromXML[".$this->getId()."]";
2436//echo "update:".ilUtil::prepareDBString(($this->getXMLContent())).":<br>";
2437//echo "update:".htmlentities($this->getXMLContent()).":<br>";
2438
2439 $content = $this->getXMLContent();
2440
2441 $this->log->debug("ilPageObject, updateFromXML(): content: ".substr($content, 0, 100));
2442
2443 $this->buildDom(true);
2444 $dom_doc = $this->getDomDoc();
2445
2446 $iel = $this->containsDeactivatedElements($content);
2447 $inl = $this->containsIntLinks($content);
2448
2449 $ilDB->update("page_object", array(
2450 "content" => array("clob", $content),
2451 "parent_id" => array("integer", $this->getParentId()),
2452 "last_change_user" => array("integer", $ilUser->getId()),
2453 "last_change" => array("timestamp", ilUtil::now()),
2454 "active" => array("integer", $this->getActive()),
2455 "activation_start" => array("timestamp", $this->getActivationStart()),
2456 "activation_end" => array("timestamp", $this->getActivationEnd()),
2457 "inactive_elements" => array("integer", $iel),
2458 "int_links" => array("integer", $inl),
2459 ), array(
2460 "page_id" => array("integer", $this->getId()),
2461 "parent_type" => array("text", $this->getParentType()),
2462 "lang" => array("text", $this->getLanguage())
2463 ));
2464
2465 // after update event
2466 $this->__afterUpdate($dom_doc, $content);
2467
2468 $this->log->debug("ilPageObject, updateFromXML(): end");
2469
2470 return true;
2471 }
2472
2479 protected final function __afterUpdate($a_domdoc, $a_xml, $a_creation = false, $a_empty = false)
2480 {
2481 // we do not need this if we are creating an empty page
2482 if (!$a_creation || !$a_empty)
2483 {
2484 // save internal link information
2485 // the page object is responsible to do this, since it "offers" the
2486 // internal link feature pc and page classes
2487 $this->saveInternalLinks($a_domdoc);
2488
2489 // save style usage
2490 $this->saveStyleUsage($a_domdoc);
2491
2492 // pc classes hook
2493 include_once("./Services/COPage/classes/class.ilCOPagePCDef.php");
2495 foreach ($defs as $def)
2496 {
2498 $cl = $def["pc_class"];
2499 call_user_func($def["pc_class"].'::afterPageUpdate', $this, $a_domdoc, $a_xml, $a_creation);
2500 }
2501 }
2502
2503 // call page hook
2504 $this->afterUpdate($a_domdoc, $a_xml);
2505
2506 // call update listeners
2507 $this->callUpdateListeners();
2508 }
2509
2516 function afterUpdate()
2517 {
2518 }
2519
2520
2525 function update($a_validate = true, $a_no_history = false)
2526 {
2527 global $lng, $ilDB, $ilUser, $ilLog, $ilCtrl;
2528
2529 $this->log->debug("ilPageObject, update(): start, id: ".$this->getId());
2530
2531 $lm_set = new ilSetting("lm");
2532
2533//echo "<br>**".$this->getId()."**";
2534//echo "<br>PageObject::update[".$this->getId()."],validate($a_validate)";
2535//echo "\n<br>dump_all2:".$this->dom->dump_mem(0, "UTF-8").":";
2536//echo "\n<br>PageObject::update:".$this->getXMLFromDom().":";
2537//debug_print_backtrace();
2538//echo "<br>PageObject::update:".htmlentities($this->getXMLFromDom()); exit;
2539
2540 // add missing pc ids
2541 if (!$this->checkPCIds())
2542 {
2543 $this->insertPCIds();
2544 }
2545
2546 // test validating
2547 if($a_validate)
2548 {
2549 $errors = $this->validateDom();
2550 }
2551//var_dump($errors); exit;
2552 if (empty($errors) && !$this->getEditLock())
2553 {
2554 include_once("./Services/User/classes/class.ilUserUtil.php");
2555 $lock = $this->getEditLockInfo();
2556 $errors[0] = array(0 => 0,
2557 1 => "nocontent#".$lng->txt("cont_not_saved_edit_lock_expired")."<br />".
2558 $lng->txt("obj_usr").": ".
2559 ilUserUtil::getNamePresentation($lock["edit_lock_user"])."<br />".
2560 $lng->txt("content_until").": ".
2561 ilDatePresentation::formatDate(new ilDateTime($lock["edit_lock_until"],IL_CAL_UNIX))
2562 );
2563 }
2564
2565 if (!empty($errors))
2566 {
2567 $this->log->debug("ilPageObject, update(): errors: ".print_r($errors, true));
2568 }
2569
2570//echo "-".htmlentities($this->getXMLFromDom())."-"; exit;
2571 if(empty($errors))
2572 {
2573 // @todo 1: is this page type or pc content type
2574 // related -> plugins should be able to hook in!?
2576
2577 // get xml content
2578 $content = $this->getXMLFromDom();
2579 $dom_doc = $this->getDomDoc();
2580
2581 // this needs to be locked
2582
2583 // write history entry
2584 $old_set = $ilDB->query("SELECT * FROM page_object WHERE ".
2585 "page_id = ".$ilDB->quote($this->getId(), "integer")." AND ".
2586 "parent_type = ".$ilDB->quote($this->getParentType(), "text")." AND ".
2587 "lang = ".$ilDB->quote($this->getLanguage(), "text"));
2588 $last_nr_set = $ilDB->query("SELECT max(nr) as mnr FROM page_history WHERE ".
2589 "page_id = ".$ilDB->quote($this->getId(), "integer")." AND ".
2590 "parent_type = ".$ilDB->quote($this->getParentType(), "text")." AND ".
2591 "lang = ".$ilDB->quote($this->getLanguage(), "text"));
2592 $last_nr = $ilDB->fetchAssoc($last_nr_set);
2593 if ($old_rec = $ilDB->fetchAssoc($old_set))
2594 {
2595 // only save, if something has changed
2596 // added user id to the check for ilias 5.0, 7.10.2014
2597 if (($content != $old_rec["content"] || $ilUser->getId() != $old_rec["last_change_user"]) &&
2598 !$a_no_history && !$this->history_saved && $lm_set->get("page_history", 1))
2599 {
2600 if ($old_rec["content"] != "<PageObject></PageObject>")
2601 {
2602 $ilDB->manipulateF("DELETE FROM page_history WHERE ".
2603 "page_id = %s AND parent_type = %s AND hdate = %s AND lang = %s",
2604 array("integer", "text", "timestamp", "text"),
2605 array($old_rec["page_id"], $old_rec["parent_type"], $old_rec["last_change"], $old_rec["lang"]));
2606
2607 // the following lines are a workaround for
2608 // bug 6741
2609 $last_c = $old_rec["last_change"];
2610 if ($last_c == "")
2611 {
2612 $last_c = ilUtil::now();
2613 }
2614
2615 $ilDB->insert("page_history", array(
2616 "page_id" => array("integer", $old_rec["page_id"]),
2617 "parent_type" => array("text", $old_rec["parent_type"]),
2618 "lang" => array("text", $old_rec["lang"]),
2619 "hdate" => array("timestamp", $last_c),
2620 "parent_id" => array("integer", $old_rec["parent_id"]),
2621 "content" => array("clob", $old_rec["content"]),
2622 "user_id" => array("integer", $old_rec["last_change_user"]),
2623 "ilias_version" => array("text", ILIAS_VERSION_NUMERIC),
2624 "nr" => array("integer", (int) $last_nr["mnr"] + 1)
2625 ));
2626
2627 $old_content = $old_rec["content"];
2628 $old_domdoc = new DOMDocument();
2629 $old_nr = $last_nr["mnr"] + 1;
2630 $old_domdoc->loadXML('<?xml version="1.0" encoding="UTF-8"?>'.$old_content);
2631
2632 // after history entry creation event
2633 $this->__afterHistoryEntry($old_domdoc, $old_content, $old_nr);
2634
2635 $this->history_saved = true; // only save one time
2636 }
2637 else
2638 {
2639 $this->history_saved = true; // do not save on first change
2640 }
2641 }
2642 }
2643//echo htmlentities($content);
2644 $em = (trim($content) == "<PageObject/>")
2645 ? 1
2646 : 0;
2647
2648 // @todo: pass dom instead?
2649 $iel = $this->containsDeactivatedElements($content);
2650 $inl = $this->containsIntLinks($content);
2651
2652 $ilDB->update("page_object", array(
2653 "content" => array("clob", $content),
2654 "parent_id" => array("integer", $this->getParentId()),
2655 "last_change_user" => array("integer", $ilUser->getId()),
2656 "last_change" => array("timestamp", ilUtil::now()),
2657 "is_empty" => array("integer", $em),
2658 "active" => array("integer", $this->getActive()),
2659 "activation_start" => array("timestamp", $this->getActivationStart()),
2660 "activation_end" => array("timestamp", $this->getActivationEnd()),
2661 "show_activation_info" => array("integer", $this->getShowActivationInfo()),
2662 "inactive_elements" => array("integer", $iel),
2663 "int_links" => array("integer", $inl),
2664 ), array(
2665 "page_id" => array("integer", $this->getId()),
2666 "parent_type" => array("text", $this->getParentType()),
2667 "lang" => array("text", $this->getLanguage())
2668 ));
2669
2670 // after update event
2671 $this->__afterUpdate($dom_doc, $content);
2672
2673 $this->log->debug("ilPageObject, update(): updated and returning true, content: ".substr($this->getXMLContent(), 0, 100));
2674
2675//echo "<br>PageObject::update:".htmlentities($this->getXMLContent()).":";
2676 return true;
2677 }
2678 else
2679 {
2680 return $errors;
2681 }
2682 }
2683
2684
2685
2689 function delete()
2690 {
2691 global $ilDB;
2692
2693 $copg_logger = ilLoggerFactory::getLogger('copg');
2694 $copg_logger->debug("ilPageObject: Delete called for ID '".$this->getId()."',".
2695 " parent type: '".$this->getParentType()."', ".
2696 " hist nr: '".$this->old_nr."', ".
2697 " lang: '".$this->getLanguage()."', "
2698 );
2699
2700 $mobs = array();
2701 $files = array();
2702
2703 if (!$this->page_not_found)
2704 {
2705 $this->buildDom();
2706 $mobs = $this->collectMediaObjects(false);
2707 }
2708 include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
2709 $mobs2 = ilObjMediaObject::_getMobsOfObject($this->getParentType().":pg", $this->getId(), false);
2710 foreach ($mobs2 as $m)
2711 {
2712 if (!in_array($m, $mobs))
2713 {
2714 $mobs[] = $m;
2715 }
2716 }
2717
2718 $copg_logger->debug("ilPageObject: ... found ".count($mobs)." media objects.");
2719
2720 $this->__beforeDelete();
2721
2722 // delete style usages
2723 $this->deleteStyleUsages(false);
2724
2725 // delete internal links
2726 $this->deleteInternalLinks();
2727
2728 // delete all mob usages
2729 ilObjMediaObject::_deleteAllUsages($this->getParentType().":pg", $this->getId());
2730
2731 // delete news
2732 include_once("./Services/News/classes/class.ilNewsItem.php");
2734 $this->getParentType(), $this->getId(), "pg");
2735
2736 // delete page_object entry
2737 $ilDB->manipulate("DELETE FROM page_object ".
2738 "WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
2739 " AND parent_type= ".$ilDB->quote($this->getParentType(), "text"));
2740 //$this->ilias->db->query($query);
2741
2742 // delete media objects
2743 foreach ($mobs as $mob_id)
2744 {
2745 $copg_logger->debug("ilPageObject: ... processing mob ".$mob_id.".");
2746
2747 if(ilObject::_lookupType($mob_id) != 'mob')
2748 {
2749 $copg_logger->debug("ilPageObject: ... type mismatch. Ignoring mob ".$mob_id.".");
2750 continue;
2751 }
2752
2753 if (ilObject::_exists($mob_id))
2754 {
2755 $copg_logger->debug("ilPageObject: ... delete mob ".$mob_id.".");
2756
2757 $mob_obj =& new ilObjMediaObject($mob_id);
2758 $mob_obj->delete();
2759 }
2760 else
2761 {
2762 $copg_logger->debug("ilPageObject: ... missing mob ".$mob_id.".");
2763 }
2764 }
2765
2766
2767 /* delete public and private notes (see PageObjectGUI->getNotesHTML())
2768 as they can be seen as personal data we are keeping them for now
2769 include_once("Services/Notes/classes/class.ilNote.php");
2770 foreach(array(IL_NOTE_PRIVATE, IL_NOTE_PUBLIC) as $note_type)
2771 {
2772 foreach(ilNote::_getNotesOfObject($this->getParentId(), $this->getId(),
2773 $this->getParentType(), $note_type) as $note)
2774 {
2775 $note->delete();
2776 }
2777 }
2778 */
2779 }
2780
2786 protected final function __beforeDelete()
2787 {
2788 // pc classes hook
2789 include_once("./Services/COPage/classes/class.ilCOPagePCDef.php");
2791 foreach ($defs as $def)
2792 {
2794 $cl = $def["pc_class"];
2795 call_user_func($def["pc_class"].'::beforePageDelete', $this);
2796 }
2797 }
2798
2804 protected final function __afterHistoryEntry($a_old_domdoc, $a_old_content, $a_old_nr)
2805 {
2806 // save style usage
2807 $this->saveStyleUsage($a_old_domdoc, $a_old_nr);
2808
2809 // pc classes hook
2810 include_once("./Services/COPage/classes/class.ilCOPagePCDef.php");
2812 foreach ($defs as $def)
2813 {
2815 $cl = $def["pc_class"];
2816 call_user_func($def["pc_class"].'::afterPageHistoryEntry', $this, $a_old_domdoc, $a_old_content, $a_old_nr);
2817 }
2818 }
2819
2825 function saveStyleUsage($a_domdoc, $a_old_nr = 0)
2826 {
2827 global $ilDB;
2828
2829 // media aliases
2830 $xpath = new DOMXPath($a_domdoc);
2831 $path = "//Paragraph | //Section | //MediaAlias | //FileItem".
2832 " | //Table | //TableData | //Tabs | //List";
2833 $nodes = $xpath->query($path);
2834 $usages = array();
2835 foreach($nodes as $node)
2836 {
2837 switch ($node->localName)
2838 {
2839 case "Paragraph":
2840 $sname = $node->getAttribute("Characteristic");
2841 $stype = "text_block";
2842 $template = 0;
2843 break;
2844
2845 case "Section":
2846 $sname = $node->getAttribute("Characteristic");
2847 $stype = "section";
2848 $template = 0;
2849 break;
2850
2851 case "MediaAlias":
2852 $sname = $node->getAttribute("Class");
2853 $stype = "media_cont";
2854 $template = 0;
2855 break;
2856
2857 case "FileItem":
2858 $sname = $node->getAttribute("Class");
2859 $stype = "flist_li";
2860 $template = 0;
2861 break;
2862
2863 case "Table":
2864 $sname = $node->getAttribute("Template");
2865 if ($sname == "")
2866 {
2867 $sname = $node->getAttribute("Class");
2868 $stype = "table";
2869 $template = 0;
2870 }
2871 else
2872 {
2873 $stype = "table";
2874 $template = 1;
2875 }
2876 break;
2877
2878 case "TableData":
2879 $sname = $node->getAttribute("Class");
2880 $stype = "table_cell";
2881 $template = 0;
2882 break;
2883
2884 case "Tabs":
2885 $sname = $node->getAttribute("Template");
2886 if ($sname != "")
2887 {
2888 if ($node->getAttribute("Type") == "HorizontalAccordion")
2889 {
2890 $stype = "haccordion";
2891 }
2892 if ($node->getAttribute("Type") == "VerticalAccordion")
2893 {
2894 $stype = "vaccordion";
2895 }
2896 }
2897 $template = 1;
2898 break;
2899
2900 case "List":
2901 $sname = $node->getAttribute("Class");
2902 if ($node->getAttribute("Type") == "Ordered")
2903 {
2904 $stype = "list_o";
2905 }
2906 else
2907 {
2908 $stype = "list_u";
2909 }
2910 $template = 0;
2911 break;
2912 }
2913 if ($sname != "" && $stype != "")
2914 {
2915 $usages[$sname.":".$stype.":".$template] = array("sname" => $sname,
2916 "stype" => $stype, "template" => $template);
2917 }
2918 }
2919
2920
2921 $this->deleteStyleUsages($a_old_nr);
2922
2923 foreach ($usages as $u)
2924 {
2925 $ilDB->manipulate("INSERT INTO page_style_usage ".
2926 "(page_id, page_type, page_lang, page_nr, template, stype, sname) VALUES (".
2927 $ilDB->quote($this->getId(), "integer").",".
2928 $ilDB->quote($this->getParentType(), "text").",".
2929 $ilDB->quote($this->getLanguage(), "text").",".
2930 $ilDB->quote($a_old_nr, "integer").",".
2931 $ilDB->quote($u["template"], "integer").",".
2932 $ilDB->quote($u["stype"], "text").",".
2933 $ilDB->quote($u["sname"], "text").
2934 ")");
2935 }
2936 }
2937
2944 function deleteStyleUsages($a_old_nr = 0)
2945 {
2946 global $ilDB;
2947
2948 if ($a_old_nr !== false)
2949 {
2950 $and_old_nr = " AND page_nr = ".$ilDB->quote($a_old_nr, "integer");
2951 }
2952
2953 $ilDB->manipulate("DELETE FROM page_style_usage WHERE ".
2954 " page_id = ".$ilDB->quote($this->getId(), "integer").
2955 " AND page_type = ".$ilDB->quote($this->getParentType(), "text").
2956 " AND page_lang = ".$ilDB->quote($this->getLanguage(), "text").
2957 $and_old_nr
2958 );
2959 }
2960
2961
2966 // @todo: move to content include class
2968 {
2969 include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
2970 include_once("./Modules/File/classes/class.ilObjFile.php");
2972 $this->getId());
2973 $files = ilObjFile::_getFilesOfObject($this->getParentType().":pg",
2974 $this->getId());
2975 $objs = array_merge($mobs, $files);
2977 }
2978
2986 {
2987 include_once("./Services/Link/classes/class.ilInternalLink.php");
2989 $this->getLanguage());
2990 }
2991
2992
2998 // @todo: move to specific classes, internal link use info
2999 function saveInternalLinks($a_domdoc)
3000 {
3001 global $ilDB;
3002
3003 $this->deleteInternalLinks();
3004
3005 // query IntLink elements
3006 $xpath = new DOMXPath($a_domdoc);
3007 $nodes = $xpath->query('//IntLink');
3008 foreach($nodes as $node)
3009 {
3010 $link_type = $node->getAttribute("Type");
3011
3012 switch ($link_type)
3013 {
3014 case "StructureObject":
3015 $t_type = "st";
3016 break;
3017
3018 case "PageObject":
3019 $t_type = "pg";
3020 break;
3021
3022 case "GlossaryItem":
3023 $t_type = "git";
3024 break;
3025
3026 case "MediaObject":
3027 $t_type = "mob";
3028 break;
3029
3030 case "RepositoryItem":
3031 $t_type = "obj";
3032 break;
3033
3034 case "File":
3035 $t_type = "file";
3036 break;
3037
3038 case "WikiPage":
3039 $t_type = "wpage";
3040 break;
3041
3042 case "User":
3043 $t_type = "user";
3044 break;
3045 }
3046
3047 $target = $node->getAttribute("Target");
3048 $target_arr = explode("_", $target);
3049 $t_id = $target_arr[count($target_arr) - 1];
3050
3051 // link to other internal object
3052 if (is_int(strpos($target, "__")))
3053 {
3054 $t_inst = 0;
3055 }
3056 else // link to unresolved object in other installation
3057 {
3058 $t_inst = $target_arr[1];
3059 }
3060
3061 if ($t_id > 0)
3062 {
3063 ilInternalLink::_saveLink($this->getParentType().":pg", $this->getId(), $t_type,
3064 $t_id, $t_inst, $this->getLanguage());
3065 }
3066 }
3067 }
3068
3072 function create()
3073 {
3074 $this->createFromXML();
3075 }
3076
3084 function deleteContent($a_hid, $a_update = true, $a_pcid = "")
3085 {
3086 $curr_node =& $this->getContentNode($a_hid, $a_pcid);
3087 $curr_node->unlink_node($curr_node);
3088 if ($a_update)
3089 {
3090 return $this->update();
3091 }
3092 }
3093
3094
3102 function deleteContents($a_hids, $a_update = true, $a_self_ass = false)
3103 {
3104 if (!is_array($a_hids))
3105 {
3106 return;
3107 }
3108 foreach($a_hids as $a_hid)
3109 {
3110 $a_hid = explode(":", $a_hid);
3111//echo "-".$a_hid[0]."-".$a_hid[1]."-";
3112
3113// @todo 1: hook
3114 // do not delete question nodes in assessment pages
3115 if (!$this->checkForTag("Question", $a_hid[0], $a_hid[1]) || $a_self_ass)
3116 {
3117 $curr_node =& $this->getContentNode($a_hid[0], $a_hid[1]);
3118 if (is_object($curr_node))
3119 {
3120 $parent_node = $curr_node->parent_node();
3121 if ($parent_node->node_name() != "TableRow")
3122 {
3123 $curr_node->unlink_node($curr_node);
3124 }
3125 }
3126 }
3127 }
3128 if ($a_update)
3129 {
3130 return $this->update();
3131 }
3132 }
3133
3139 function cutContents($a_hids)
3140 {
3141 $this->copyContents($a_hids);
3142 return $this->deleteContents($a_hids, true, $this->getPageConfig()->getEnableSelfAssessment());
3143 }
3144
3150 function copyContents($a_hids)
3151 {
3152 global $ilUser;
3153//var_dump($a_hids);
3154 if (!is_array($a_hids))
3155 {
3156 return;
3157 }
3158
3159 $time = date("Y-m-d H:i:s", time());
3160
3161 $hier_ids = array();
3162 $skip = array();
3163 foreach($a_hids as $a_hid)
3164 {
3165 if ($a_hid == "")
3166 {
3167 continue;
3168 }
3169 $a_hid = explode(":", $a_hid);
3170
3171 // check, whether new hid is child of existing one or vice versa
3172 reset($hier_ids);
3173 foreach($hier_ids as $h)
3174 {
3175 if($h."_" == substr($a_hid[0], 0, strlen($h) + 1))
3176 {
3177 $skip[] = $a_hid[0];
3178 }
3179 if($a_hid[0]."_" == substr($h, 0, strlen($a_hid[0]) + 1))
3180 {
3181 $skip[] = $h;
3182 }
3183 }
3184 $pc_id[$a_hid[0]] = $a_hid[1];
3185 if ($a_hid[0] != "")
3186 {
3187 $hier_ids[$a_hid[0]] = $a_hid[0];
3188 }
3189 }
3190 foreach ($skip as $s)
3191 {
3192 unset($hier_ids[$s]);
3193 }
3194 include_once("./Services/COPage/classes/class.ilPageContent.php");
3195 $hier_ids = ilPageContent::sortHierIds($hier_ids);
3196 $nr = 1;
3197 foreach($hier_ids as $hid)
3198 {
3199 $curr_node = $this->getContentNode($hid, $pc_id[$hid]);
3200 if (is_object($curr_node))
3201 {
3202 if ($curr_node->node_name() == "PageContent")
3203 {
3204 $content = $this->dom->dump_node($curr_node);
3205 // remove pc and hier ids
3206 $content = eregi_replace("PCID=\"[a-z0-9]*\"","",$content);
3207 $content = eregi_replace("HierId=\"[a-z0-9_]*\"","",$content);
3208
3209 $ilUser->addToPCClipboard($content, $time, $nr);
3210 $nr++;
3211 }
3212 }
3213 }
3214 include_once("./Modules/LearningModule/classes/class.ilEditClipboard.php");
3216 }
3217
3221 function pasteContents($a_hier_id, $a_self_ass = false)
3222 {
3223 global $ilUser;
3224
3225 $a_hid = explode(":", $a_hier_id);
3226 $content = $ilUser->getPCClipboardContent();
3227
3228 // we insert from last to first, because we insert all at the
3229 // same hier_id
3230 for ($i = count($content) - 1; $i >= 0; $i--)
3231 {
3232
3233 $c = $content[$i];
3234 $temp_dom = domxml_open_mem('<?xml version="1.0" encoding="UTF-8"?>'.$c,
3235 DOMXML_LOAD_PARSING, $error);
3236 if(empty($error))
3237 {
3238 $this->handleCopiedContent($temp_dom, $a_self_ass);
3239 $xpc = xpath_new_context($temp_dom);
3240 $path = "//PageContent";
3241 $res = xpath_eval($xpc, $path);
3242 if (count($res->nodeset) > 0)
3243 {
3244 $new_pc_node = $res->nodeset[0];
3245 $cloned_pc_node = $new_pc_node->clone_node (true);
3246 $cloned_pc_node->unlink_node ($cloned_pc_node);
3247 $this->insertContentNode ($cloned_pc_node, $a_hid[0],
3248 IL_INSERT_AFTER, $a_hid[1]);
3249 }
3250 }
3251 else
3252 {
3253//var_dump($error);
3254 }
3255 }
3256 $e = $this->update();
3257//var_dump($e);
3258 }
3259
3263 function switchEnableMultiple($a_hids, $a_update = true, $a_self_ass = false)
3264 {
3265 if (!is_array($a_hids))
3266 {
3267 return;
3268 }
3269 $obj = & $this->content_obj;
3270
3271 foreach($a_hids as $a_hid)
3272 {
3273 $a_hid = explode(":", $a_hid);
3274 $curr_node =& $this->getContentNode($a_hid[0], $a_hid[1]);
3275 if (is_object($curr_node))
3276 {
3277 if ($curr_node->node_name() == "PageContent")
3278 {
3279 $cont_obj =& $this->getContentObject($a_hid[0], $a_hid[1]);
3280 if ($cont_obj->isEnabled ())
3281 {
3282 // do not deactivate question nodes in assessment pages
3283 if (!$this->checkForTag("Question", $a_hid[0], $a_hid[1]) || $a_self_ass)
3284 {
3285 $cont_obj->disable();
3286 }
3287 }
3288 else
3289 {
3290 $cont_obj->enable();
3291 }
3292 }
3293 }
3294 }
3295
3296 if ($a_update)
3297 {
3298 return $this->update();
3299 }
3300 }
3301
3302
3310 function deleteContentFromHierId($a_hid, $a_update = true)
3311 {
3312 $hier_ids = $this->getHierIds();
3313
3314 // iterate all hierarchical ids
3315 foreach ($hier_ids as $hier_id)
3316 {
3317 // delete top level nodes only
3318 if (!is_int(strpos($hier_id, "_")))
3319 {
3320 if ($hier_id != "pg" && $hier_id >= $a_hid)
3321 {
3322 $curr_node =& $this->getContentNode($hier_id);
3323 $curr_node->unlink_node($curr_node);
3324 }
3325 }
3326 }
3327 if ($a_update)
3328 {
3329 return $this->update();
3330 }
3331 }
3332
3340 function deleteContentBeforeHierId($a_hid, $a_update = true)
3341 {
3342 $hier_ids = $this->getHierIds();
3343
3344 // iterate all hierarchical ids
3345 foreach ($hier_ids as $hier_id)
3346 {
3347 // delete top level nodes only
3348 if (!is_int(strpos($hier_id, "_")))
3349 {
3350 if ($hier_id != "pg" && $hier_id < $a_hid)
3351 {
3352 $curr_node =& $this->getContentNode($hier_id);
3353 $curr_node->unlink_node($curr_node);
3354 }
3355 }
3356 }
3357 if ($a_update)
3358 {
3359 return $this->update();
3360 }
3361 }
3362
3363
3371 function _moveContentAfterHierId(&$a_source_page, &$a_target_page, $a_hid)
3372 {
3373 $hier_ids = $a_source_page->getHierIds();
3374
3375 $copy_ids = array();
3376
3377 // iterate all hierarchical ids
3378 foreach ($hier_ids as $hier_id)
3379 {
3380 // move top level nodes only
3381 if (!is_int(strpos($hier_id, "_")))
3382 {
3383 if ($hier_id != "pg" && $hier_id >= $a_hid)
3384 {
3385 $copy_ids[] = $hier_id;
3386 }
3387 }
3388 }
3389 asort($copy_ids);
3390
3391 $parent_node =& $a_target_page->getContentNode("pg");
3392 $target_dom =& $a_target_page->getDom();
3393 $parent_childs =& $parent_node->child_nodes();
3394 $cnt_parent_childs = count($parent_childs);
3395//echo "-$cnt_parent_childs-";
3396 $first_child =& $parent_childs[0];
3397 foreach($copy_ids as $copy_id)
3398 {
3399 $source_node =& $a_source_page->getContentNode($copy_id);
3400
3401 $new_node =& $source_node->clone_node(true);
3402 $new_node->unlink_node($new_node);
3403
3404 $source_node->unlink_node($source_node);
3405
3406 if($cnt_parent_childs == 0)
3407 {
3408 $new_node =& $parent_node->append_child($new_node);
3409 }
3410 else
3411 {
3412 //$target_dom->import_node($new_node);
3413 $new_node =& $first_child->insert_before($new_node, $first_child);
3414 }
3415 $parent_childs =& $parent_node->child_nodes();
3416
3417 //$cnt_parent_childs++;
3418 }
3419
3420 $a_target_page->update();
3421 $a_source_page->update();
3422
3423 }
3424
3428 function insertContent(&$a_cont_obj, $a_pos, $a_mode = IL_INSERT_AFTER, $a_pcid = "")
3429 {
3430//echo "-".$a_pos."-".$a_pcid."-";
3431 // move mode into container elements is always INSERT_CHILD
3432 $curr_node = $this->getContentNode($a_pos, $a_pcid);
3433 $curr_name = $curr_node->node_name();
3434
3435 // @todo: try to generalize this
3436 if (($curr_name == "TableData") || ($curr_name == "PageObject") ||
3437 ($curr_name == "ListItem") || ($curr_name == "Section")
3438 || ($curr_name == "Tab") || ($curr_name == "ContentPopup"))
3439 {
3440 $a_mode = IL_INSERT_CHILD;
3441 }
3442
3443 $hid = $curr_node->get_attribute("HierId");
3444 if ($hid != "")
3445 {
3446//echo "-".$a_pos."-".$hid."-";
3447 $a_pos = $hid;
3448 }
3449
3450 if($a_mode != IL_INSERT_CHILD) // determine parent hierarchical id
3451 { // of sibling at $a_pos
3452 $pos = explode("_", $a_pos);
3453 $target_pos = array_pop($pos);
3454 $parent_pos = implode($pos, "_");
3455 }
3456 else // if we should insert a child, $a_pos is alreade the hierarchical id
3457 { // of the parent node
3458 $parent_pos = $a_pos;
3459 }
3460
3461 // get the parent node
3462 if($parent_pos != "")
3463 {
3464 $parent_node =& $this->getContentNode($parent_pos);
3465 }
3466 else
3467 {
3468 $parent_node =& $this->getNode();
3469 }
3470
3471 // count the parent children
3472 $parent_childs =& $parent_node->child_nodes();
3473 $cnt_parent_childs = count($parent_childs);
3474//echo "ZZ$a_mode";
3475 switch ($a_mode)
3476 {
3477 // insert new node after sibling at $a_pos
3478 case IL_INSERT_AFTER:
3479 $new_node =& $a_cont_obj->getNode();
3480 //$a_pos = ilPageContent::incEdId($a_pos);
3481 //$curr_node =& $this->getContentNode($a_pos);
3482//echo "behind $a_pos:";
3483 if($succ_node =& $curr_node->next_sibling())
3484 {
3485 $new_node =& $succ_node->insert_before($new_node, $succ_node);
3486 }
3487 else
3488 {
3489//echo "movin doin append_child";
3490 $new_node =& $parent_node->append_child($new_node);
3491 }
3492 $a_cont_obj->setNode($new_node);
3493 break;
3494
3495 case IL_INSERT_BEFORE:
3496//echo "INSERT_BEF";
3497 $new_node =& $a_cont_obj->getNode();
3498 $succ_node =& $this->getContentNode($a_pos);
3499 $new_node =& $succ_node->insert_before($new_node, $succ_node);
3500 $a_cont_obj->setNode($new_node);
3501 break;
3502
3503 // insert new node as first child of parent $a_pos (= $a_parent)
3504 case IL_INSERT_CHILD:
3505//echo "insert as child:parent_childs:$cnt_parent_childs:<br>";
3506 $new_node =& $a_cont_obj->getNode();
3507 if($cnt_parent_childs == 0)
3508 {
3509 $new_node =& $parent_node->append_child($new_node);
3510 }
3511 else
3512 {
3513 $new_node =& $parent_childs[0]->insert_before($new_node, $parent_childs[0]);
3514 }
3515 $a_cont_obj->setNode($new_node);
3516//echo "PP";
3517 break;
3518 }
3519
3520 //check for PlaceHolder to remove in EditMode-keep in Layout Mode
3521 if (!$this->getPageConfig()->getEnablePCType("PlaceHolder")) {
3522 $sub_nodes = $curr_node->child_nodes() ;
3523 foreach ( $sub_nodes as $sub_node ) {
3524 if ($sub_node->node_name() == "PlaceHolder") {
3525 $curr_node->unlink_node();
3526 }
3527 }
3528 }
3529 }
3530
3534 function insertContentNode(&$a_cont_node, $a_pos, $a_mode = IL_INSERT_AFTER, $a_pcid = "")
3535 {
3536 // move mode into container elements is always INSERT_CHILD
3537 $curr_node = $this->getContentNode($a_pos, $a_pcid);
3538 $curr_name = $curr_node->node_name();
3539
3540 // @todo: try to generalize
3541 if (($curr_name == "TableData") || ($curr_name == "PageObject") ||
3542 ($curr_name == "ListItem") || ($curr_name == "Section")
3543 || ($curr_name == "Tab") || ($curr_name == "ContentPopup"))
3544 {
3545 $a_mode = IL_INSERT_CHILD;
3546 }
3547
3548 $hid = $curr_node->get_attribute("HierId");
3549 if ($hid != "")
3550 {
3551 $a_pos = $hid;
3552 }
3553
3554 if($a_mode != IL_INSERT_CHILD) // determine parent hierarchical id
3555 { // of sibling at $a_pos
3556 $pos = explode("_", $a_pos);
3557 $target_pos = array_pop($pos);
3558 $parent_pos = implode($pos, "_");
3559 }
3560 else // if we should insert a child, $a_pos is alreade the hierarchical id
3561 { // of the parent node
3562 $parent_pos = $a_pos;
3563 }
3564
3565 // get the parent node
3566 if($parent_pos != "")
3567 {
3568 $parent_node =& $this->getContentNode($parent_pos);
3569 }
3570 else
3571 {
3572 $parent_node =& $this->getNode();
3573 }
3574
3575 // count the parent children
3576 $parent_childs =& $parent_node->child_nodes();
3577 $cnt_parent_childs = count($parent_childs);
3578
3579 switch ($a_mode)
3580 {
3581 // insert new node after sibling at $a_pos
3582 case IL_INSERT_AFTER:
3583 //$new_node =& $a_cont_obj->getNode();
3584 if($succ_node = $curr_node->next_sibling())
3585 {
3586 $a_cont_node = $succ_node->insert_before($a_cont_node, $succ_node);
3587 }
3588 else
3589 {
3590 $a_cont_node = $parent_node->append_child($a_cont_node);
3591 }
3592 //$a_cont_obj->setNode($new_node);
3593 break;
3594
3595 case IL_INSERT_BEFORE:
3596 //$new_node =& $a_cont_obj->getNode();
3597 $succ_node = $this->getContentNode($a_pos);
3598 $a_cont_node = $succ_node->insert_before($a_cont_node, $succ_node);
3599 //$a_cont_obj->setNode($new_node);
3600 break;
3601
3602 // insert new node as first child of parent $a_pos (= $a_parent)
3603 case IL_INSERT_CHILD:
3604 //$new_node =& $a_cont_obj->getNode();
3605 if($cnt_parent_childs == 0)
3606 {
3607 $a_cont_node = $parent_node->append_child($a_cont_node);
3608 }
3609 else
3610 {
3611 $a_cont_node = $parent_childs[0]->insert_before($a_cont_node, $parent_childs[0]);
3612 }
3613 //$a_cont_obj->setNode($new_node);
3614 break;
3615 }
3616 }
3617
3622 function moveContentBefore($a_source, $a_target, $a_spcid = "", $a_tpcid = "")
3623 {
3624 if($a_source == $a_target)
3625 {
3626 return;
3627 }
3628
3629 // clone the node
3630 $content =& $this->getContentObject($a_source, $a_spcid);
3631 $source_node =& $content->getNode();
3632 $clone_node =& $source_node->clone_node(true);
3633
3634 // delete source node
3635 $this->deleteContent($a_source, false, $a_spcid);
3636
3637 // insert cloned node at target
3638 $content->setNode($clone_node);
3639 $this->insertContent($content, $a_target, IL_INSERT_BEFORE, $a_tpcid);
3640 return $this->update();
3641
3642 }
3643
3648 function moveContentAfter($a_source, $a_target, $a_spcid = "", $a_tpcid = "")
3649 {
3650 if($a_source == $a_target)
3651 {
3652 return;
3653 }
3654
3655 // clone the node
3656 $content =& $this->getContentObject($a_source, $a_spcid);
3657 $source_node =& $content->getNode();
3658 $clone_node =& $source_node->clone_node(true);
3659
3660 // delete source node
3661 $this->deleteContent($a_source, false, $a_spcid);
3662
3663 // insert cloned node at target
3664 $content->setNode($clone_node);
3665 $this->insertContent($content, $a_target, IL_INSERT_AFTER, $a_tpcid);
3666 return $this->update();
3667 }
3668
3672 // @todo: move to paragraph
3673 function bbCode2XML(&$a_content)
3674 {
3675 $a_content = eregi_replace("\[com\]","<Comment>",$a_content);
3676 $a_content = eregi_replace("\[\/com\]","</Comment>",$a_content);
3677 $a_content = eregi_replace("\[emp]","<Emph>",$a_content);
3678 $a_content = eregi_replace("\[\/emp\]","</Emph>",$a_content);
3679 $a_content = eregi_replace("\[str]","<Strong>",$a_content);
3680 $a_content = eregi_replace("\[\/str\]","</Strong>",$a_content);
3681 }
3682
3687 function insertInstIntoIDs($a_inst, $a_res_ref_to_obj_id = true)
3688 {
3689 // insert inst id into internal links
3690 $xpc = xpath_new_context($this->dom);
3691 $path = "//IntLink";
3692 $res =& xpath_eval($xpc, $path);
3693 for($i = 0; $i < count($res->nodeset); $i++)
3694 {
3695 $target = $res->nodeset[$i]->get_attribute("Target");
3696 $type = $res->nodeset[$i]->get_attribute("Type");
3697
3698 if (substr($target, 0, 4) == "il__")
3699 {
3700 $id = substr($target, 4, strlen($target) - 4);
3701
3702 // convert repository links obj_<ref_id> to <type>_<obj_id>
3703 // this leads to bug 6685.
3704 if ($a_res_ref_to_obj_id && $type == "RepositoryItem")
3705 {
3706 $id_arr = explode("_", $id);
3707
3708 // changed due to bug 6685
3709 $ref_id = $id_arr[1];
3710 $obj_id = ilObject::_lookupObjId($id_arr[1]);
3711
3712 $otype = ilObject::_lookupType($obj_id);
3713 if ($obj_id > 0)
3714 {
3715 // changed due to bug 6685
3716 // the ref_id should be used, if the content is
3717 // imported on the same installation
3718 // the obj_id should be used, if a different
3719 // installation imports, but has an import_id for
3720 // the object id.
3721 $id = $otype."_".$obj_id."_".$ref_id;
3722 //$id = $otype."_".$ref_id;
3723 }
3724 }
3725 $new_target = "il_".$a_inst."_".$id;
3726 $res->nodeset[$i]->set_attribute("Target", $new_target);
3727 }
3728 }
3729 unset($xpc);
3730
3731 // @todo: move to media/fileitems/questions, ...
3732
3733 // insert inst id into media aliases
3734 $xpc = xpath_new_context($this->dom);
3735 $path = "//MediaAlias";
3736 $res =& xpath_eval($xpc, $path);
3737 for($i = 0; $i < count($res->nodeset); $i++)
3738 {
3739 $origin_id = $res->nodeset[$i]->get_attribute("OriginId");
3740 if (substr($origin_id, 0, 4) == "il__")
3741 {
3742 $new_id = "il_".$a_inst."_".substr($origin_id, 4, strlen($origin_id) - 4);
3743 $res->nodeset[$i]->set_attribute("OriginId", $new_id);
3744 }
3745 }
3746 unset($xpc);
3747
3748 // insert inst id file item identifier entries
3749 $xpc = xpath_new_context($this->dom);
3750 $path = "//FileItem/Identifier";
3751 $res =& xpath_eval($xpc, $path);
3752 for($i = 0; $i < count($res->nodeset); $i++)
3753 {
3754 $origin_id = $res->nodeset[$i]->get_attribute("Entry");
3755 if (substr($origin_id, 0, 4) == "il__")
3756 {
3757 $new_id = "il_".$a_inst."_".substr($origin_id, 4, strlen($origin_id) - 4);
3758 $res->nodeset[$i]->set_attribute("Entry", $new_id);
3759 }
3760 }
3761 unset($xpc);
3762
3763 // insert inst id into question references
3764 $xpc = xpath_new_context($this->dom);
3765 $path = "//Question";
3766 $res =& xpath_eval($xpc, $path);
3767 for($i = 0; $i < count($res->nodeset); $i++)
3768 {
3769 $qref = $res->nodeset[$i]->get_attribute("QRef");
3770//echo "<br>setted:".$qref;
3771 if (substr($qref, 0, 4) == "il__")
3772 {
3773 $new_id = "il_".$a_inst."_".substr($qref, 4, strlen($qref) - 4);
3774//echo "<br>setting:".$new_id;
3775 $res->nodeset[$i]->set_attribute("QRef", $new_id);
3776 }
3777 }
3778 unset($xpc);
3779
3780 // insert inst id into content snippets
3781 $xpc = xpath_new_context($this->dom);
3782 $path = "//ContentInclude";
3783 $res =& xpath_eval($xpc, $path);
3784 for($i = 0; $i < count($res->nodeset); $i++)
3785 {
3786 $ci = $res->nodeset[$i]->get_attribute("InstId");
3787 if ($ci == "")
3788 {
3789 $res->nodeset[$i]->set_attribute("InstId", $a_inst);
3790 }
3791 }
3792 unset($xpc);
3793
3794 }
3795
3799 function checkPCIds()
3800 {
3801 $this->builddom();
3802 $mydom = $this->dom;
3803
3804 $sep = $path = "";
3805 foreach ($this->id_elements as $el)
3806 {
3807 $path.= $sep."//".$el."[not(@PCID)]";
3808 $sep = " | ";
3809 $path.= $sep."//".$el."[@PCID='']";
3810 }
3811
3812 $xpc = xpath_new_context($mydom);
3813 $res = & xpath_eval($xpc, $path);
3814
3815 if (count ($res->nodeset) > 0)
3816 {
3817 return false;
3818 }
3819 return true;
3820 }
3821
3828 function getAllPCIds()
3829 {
3830 $this->builddom();
3831 $mydom = $this->dom;
3832
3833 $pcids = array();
3834
3835 $sep = $path = "";
3836 foreach ($this->id_elements as $el)
3837 {
3838 $path.= $sep."//".$el."[@PCID]";
3839 $sep = " | ";
3840 }
3841
3842 // get existing ids
3843 $xpc = xpath_new_context($mydom);
3844 $res = & xpath_eval($xpc, $path);
3845
3846 for ($i = 0; $i < count ($res->nodeset); $i++)
3847 {
3848 $node = $res->nodeset[$i];
3849 $pcids[] = $node->get_attribute("PCID");
3850 }
3851 return $pcids;
3852 }
3853
3860 function existsPCId($a_pc_id)
3861 {
3862 $this->builddom();
3863 $mydom = $this->dom;
3864
3865 $pcids = array();
3866
3867 $sep = $path = "";
3868 foreach ($this->id_elements as $el)
3869 {
3870 $path.= $sep."//".$el."[@PCID='".$a_pc_id."']";
3871 $sep = " | ";
3872 }
3873
3874 // get existing ids
3875 $xpc = xpath_new_context($mydom);
3876 $res = & xpath_eval($xpc, $path);
3877 return (count($res->nodeset) > 0);
3878 }
3879
3886 function generatePcId($a_pc_ids = false)
3887 {
3888 if ($a_pc_ids === false)
3889 {
3890 $a_pc_ids = $this->getAllPCIds();
3891 }
3892 $id = ilUtil::randomHash(10, $a_pc_ids);
3893 return $id;
3894 }
3895
3896
3900 function insertPCIds()
3901 {
3902 $this->builddom();
3903 $mydom = $this->dom;
3904
3905 $pcids = $this->getAllPCIds();
3906
3907 // add missing ones
3908 $sep = $path = "";
3909 foreach ($this->id_elements as $el)
3910 {
3911 $path.= $sep."//".$el."[not(@PCID)]";
3912 $sep = " | ";
3913 $path.= $sep."//".$el."[@PCID='']";
3914 $sep = " | ";
3915 }
3916 $xpc = xpath_new_context($mydom);
3917 $res = & xpath_eval($xpc, $path);
3918
3919 for ($i = 0; $i < count ($res->nodeset); $i++)
3920 {
3921 $node = $res->nodeset[$i];
3922 $id = ilUtil::randomHash(10, $pcids);
3923 $pcids[] = $id;
3924//echo "setting-".$id."-";
3925 $res->nodeset[$i]->set_attribute("PCID", $id);
3926 }
3927 }
3928
3933 {
3934 $this->builddom();
3935 $this->addHierIds();
3936 $mydom = $this->dom;
3937
3938 // get existing ids
3939 $path = "//PageContent";
3940 $xpc = xpath_new_context($mydom);
3941 $res = & xpath_eval($xpc, $path);
3942
3943 $hashes = array();
3944 require_once("./Services/COPage/classes/class.ilPCParagraph.php");
3945 for ($i = 0; $i < count ($res->nodeset); $i++)
3946 {
3947 $hier_id = $res->nodeset[$i]->get_attribute("HierId");
3948 $pc_id = $res->nodeset[$i]->get_attribute("PCID");
3949 $dump = $mydom->dump_node($res->nodeset[$i]);
3950 if (($hpos = strpos($dump, ' HierId="'.$hier_id.'"')) > 0)
3951 {
3952 $dump = substr($dump, 0, $hpos).
3953 substr($dump, $hpos + strlen(' HierId="'.$hier_id.'"'));
3954 }
3955
3956 $childs = $res->nodeset[$i]->child_nodes();
3957 $content = "";
3958 if ($childs[0] && $childs[0]->node_name() == "Paragraph")
3959 {
3960 $content = $mydom->dump_node($childs[0]);
3961 $content = substr($content, strpos($content, ">") + 1,
3962 strrpos($content, "<") - (strpos($content, ">") + 1));
3963//var_dump($content);
3964 $content = ilPCParagraph::xml2output($content);
3965//var_dump($content);
3966 }
3967 //$hashes[$hier_id] =
3968 // array("PCID" => $pc_id, "hash" => md5($dump));
3969 $hashes[$pc_id] =
3970 array("hier_id" => $hier_id, "hash" => md5($dump), "content" => $content);
3971 }
3972
3973 return $hashes;
3974 }
3975
3979// @todo: move to questions
3981 {
3982 $this->builddom();
3983 $mydom = $this->dom;
3984
3985 // Get question IDs
3986 $path = "//Question";
3987 $xpc = xpath_new_context($mydom);
3988 $res = & xpath_eval($xpc, $path);
3989
3990 $q_ids = array();
3991 include_once("./Services/Link/classes/class.ilInternalLink.php");
3992 for ($i = 0; $i < count ($res->nodeset); $i++)
3993 {
3994 $qref = $res->nodeset[$i]->get_attribute("QRef");
3995
3996 $inst_id = ilInternalLink::_extractInstOfTarget($qref);
3998
3999 if (!($inst_id > 0))
4000 {
4001 if ($obj_id > 0)
4002 {
4003 $q_ids[] = $obj_id;
4004 }
4005 }
4006 }
4007 return $q_ids;
4008 }
4009
4010// @todo: move to paragraph
4011 function send_paragraph ($par_id, $filename)
4012 {
4013 $this->builddom();
4014
4015 $mydom = $this->dom;
4016
4017 $xpc = xpath_new_context($mydom);
4018
4019 //$path = "//PageContent[position () = $par_id]/Paragraph";
4020 //$path = "//Paragraph[$par_id]";
4021 $path = "/descendant::Paragraph[position() = $par_id]";
4022
4023 $res = & xpath_eval($xpc, $path);
4024
4025 if (count ($res->nodeset) != 1)
4026 die ("Should not happen");
4027
4028 $context_node = $res->nodeset[0];
4029
4030 // get plain text
4031
4032 $childs = $context_node->child_nodes();
4033
4034 for($j=0; $j<count($childs); $j++)
4035 {
4036 $content .= $mydom->dump_node($childs[$j]);
4037 }
4038
4039 $content = str_replace("<br />", "\n", $content);
4040 $content = str_replace("<br/>", "\n", $content);
4041
4042 $plain_content = html_entity_decode($content);
4043
4044 ilUtil::deliverData($plain_content, $filename);
4045 /*
4046 $file_type = "application/octet-stream";
4047 header("Content-type: ".$file_type);
4048 header("Content-disposition: attachment; filename=\"$filename\"");
4049 echo $plain_content;*/
4050 exit();
4051 }
4052
4056// @todo: deprecated?
4057 function getFO()
4058 {
4059 $xml = $this->getXMLFromDom(false, true, true);
4060 $xsl = file_get_contents("./Services/COPage/xsl/page_fo.xsl");
4061 $args = array( '/_xml' => $xml, '/_xsl' => $xsl );
4062 $xh = xslt_create();
4063
4064 $params = array ();
4065
4066
4067 $fo = xslt_process($xh,"arg:/_xml","arg:/_xsl",NULL,$args, $params);
4068 var_dump($fo);
4069 // do some replacements
4070 $fo = str_replace("\n", "", $fo);
4071 $fo = str_replace("<br/>", "<br>", $fo);
4072 $fo = str_replace("<br>", "\n", $fo);
4073
4074 xslt_free($xh);
4075
4076 //
4077 $fo = substr($fo, strpos($fo,">") + 1);
4078//echo "<br><b>fo:</b><br>".htmlentities($fo); flush();
4079 return $fo;
4080 }
4081
4082 function registerOfflineHandler ($handler) {
4083 $this->offline_handler = $handler;
4084 }
4085
4093 {
4095 }
4096
4097
4101 static function _lookupContainsDeactivatedElements($a_id, $a_parent_type, $a_lang = "-")
4102 {
4103 global $ilDB;
4104
4105 if ($a_lang == "")
4106 {
4107 $a_lang = "-";
4108 }
4109
4110 $query = "SELECT * FROM page_object WHERE page_id = ".
4111 $ilDB->quote($a_id, "integer")." AND ".
4112 " parent_type = ".$ilDB->quote($a_parent_type, "text")." AND ".
4113 " lang = ".$ilDB->quote($a_lang, "text")." AND ".
4114 " inactive_elements = ".$ilDB->quote(1, "integer");
4115 $obj_set = $ilDB->query($query);
4116
4117 if ($obj_rec = $obj_set->fetchRow(DB_FETCHMODE_ASSOC))
4118 {
4119 return true;
4120 }
4121
4122 return false;
4123 }
4124
4131 function containsDeactivatedElements($a_content)
4132 {
4133 if (strpos($a_content, " Enabled=\"False\""))
4134 {
4135 return true;
4136 }
4137 return false;
4138 }
4139
4144 {
4145 global $ilDB;
4146
4147 $h_query = "SELECT * FROM page_history ".
4148 " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
4149 " AND parent_type = ".$ilDB->quote($this->getParentType(), "text").
4150 " AND lang = ".$ilDB->quote($this->getLanguage(), "text").
4151 " ORDER BY hdate DESC";
4152
4153 $hset = $ilDB->query($h_query);
4154 $hentries = array();
4155
4156 while ($hrec = $ilDB->fetchAssoc($hset))
4157 {
4158 $hrec["sortkey"] = (int) $hrec["nr"];
4159 $hrec["user"] = (int) $hrec["user_id"];
4160 $hentries[] = $hrec;
4161 }
4162//var_dump($hentries);
4163 return $hentries;
4164 }
4165
4169 function getHistoryEntry($a_old_nr)
4170 {
4171 global $ilDB;
4172
4173 $res = $ilDB->queryF("SELECT * FROM page_history ".
4174 " WHERE page_id = %s ".
4175 " AND parent_type = %s ".
4176 " AND nr = %s".
4177 " AND lang = %s",
4178 array("integer", "text", "integer", "text"),
4179 array($this->getId(), $this->getParentType(), $a_old_nr, $this->getLanguage()));
4180 if ($hrec = $ilDB->fetchAssoc($res))
4181 {
4182 return $hrec;
4183 }
4184
4185 return false;
4186 }
4187
4188
4195 function getHistoryInfo($a_nr)
4196 {
4197 global $ilDB;
4198
4199 // determine previous entry
4200 $and_nr = ($a_nr > 0)
4201 ? " AND nr < ".$ilDB->quote((int) $a_nr, "integer")
4202 : "";
4203 $res = $ilDB->query("SELECT MAX(nr) mnr FROM page_history ".
4204 " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
4205 " AND parent_type = ".$ilDB->quote($this->getParentType(), "text").
4206 " AND lang = ".$ilDB->quote($this->getLanguage(), "text").
4207 $and_nr);
4208 $row = $ilDB->fetchAssoc($res);
4209 if ($row["mnr"] > 0)
4210 {
4211 $res = $ilDB->query("SELECT * FROM page_history ".
4212 " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
4213 " AND parent_type = ".$ilDB->quote($this->getParentType(), "text").
4214 " AND lang = ".$ilDB->quote($this->getLanguage(), "text").
4215 " AND nr = ".$ilDB->quote((int) $row["mnr"], "integer"));
4216 $row = $ilDB->fetchAssoc($res);
4217 $ret["previous"] = $row;
4218 }
4219
4220 // determine next entry
4221 $res = $ilDB->query("SELECT MIN(nr) mnr FROM page_history ".
4222 " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
4223 " AND parent_type = ".$ilDB->quote($this->getParentType(), "text").
4224 " AND lang = ".$ilDB->quote($this->getLanguage(), "text").
4225 " AND nr > ".$ilDB->quote((int) $a_nr, "integer"));
4226 $row = $ilDB->fetchAssoc($res);
4227 if ($row["mnr"] > 0)
4228 {
4229 $res = $ilDB->query("SELECT * FROM page_history ".
4230 " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
4231 " AND parent_type = ".$ilDB->quote($this->getParentType(), "text").
4232 " AND lang = ".$ilDB->quote($this->getLanguage(), "text").
4233 " AND nr = ".$ilDB->quote((int) $row["mnr"], "integer"));
4234 $row = $ilDB->fetchAssoc($res);
4235 $ret["next"] = $row;
4236 }
4237
4238 // current
4239 if ($a_nr > 0)
4240 {
4241 $res = $ilDB->query("SELECT * FROM page_history ".
4242 " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
4243 " AND parent_type = ".$ilDB->quote($this->getParentType(), "text").
4244 " AND lang = ".$ilDB->quote($this->getLanguage(), "text").
4245 " AND nr = ".$ilDB->quote((int) $a_nr, "integer"));
4246 $row = $ilDB->fetchAssoc($res);
4247 }
4248 else
4249 {
4250 $res = $ilDB->query("SELECT page_id, last_change hdate, parent_type, parent_id, last_change_user user_id, content, lang FROM page_object ".
4251 " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
4252 " AND parent_type = ".$ilDB->quote($this->getParentType(), "text").
4253 " AND lang = ".$ilDB->quote($this->getLanguage(), "text"));
4254 $row = $ilDB->fetchAssoc($res);
4255 }
4256 $ret["current"] = $row;
4257
4258 return $ret;
4259 }
4260
4261 function addChangeDivClasses($a_hashes)
4262 {
4263 $xpc = xpath_new_context($this->dom);
4264 $path = "/*[1]";
4265 $res = xpath_eval($xpc, $path);
4266 $rnode = $res->nodeset[0];
4267
4268//echo "A";
4269 foreach($a_hashes as $pc_id => $h)
4270 {
4271//echo "B";
4272 if ($h["change"] != "")
4273 {
4274 $dc_node = $this->dom->create_element("DivClass");
4275 $dc_node->set_attribute("HierId", $h["hier_id"]);
4276 $dc_node->set_attribute("Class", "ilEdit".$h["change"]);
4277 $dc_node = $rnode->append_child($dc_node);
4278 }
4279 }
4280//echo "<br><br><br><br><br><br>".htmlentities($this->getXMLFromDom());
4281 }
4282
4289 function compareVersion($a_left, $a_right)
4290 {
4291 // get page objects
4292 include_once("./Services/COPage/classes/class.ilPageObjectFactory.php");
4293 $l_page = ilPageObjectFactory::getInstance($this->getParentType(), $this->getId(), $a_left);
4294 $r_page = ilPageObjectFactory::getInstance($this->getParentType(), $this->getId(), $a_right);
4295
4296 $l_hashes = $l_page->getPageContentsHashes();
4297 $r_hashes = $r_page->getPageContentsHashes();
4298 // determine all deleted and changed page elements
4299 foreach ($l_hashes as $pc_id => $h)
4300 {
4301 if (!isset($r_hashes[$pc_id]))
4302 {
4303 $l_hashes[$pc_id]["change"] = "Deleted";
4304 }
4305 else
4306 {
4307 if ($l_hashes[$pc_id]["hash"] != $r_hashes[$pc_id]["hash"])
4308 {
4309 $l_hashes[$pc_id]["change"] = "Modified";
4310 $r_hashes[$pc_id]["change"] = "Modified";
4311
4312 include_once("./Services/COPage/mediawikidiff/class.WordLevelDiff.php");
4313 // if modified element is a paragraph, highlight changes
4314 if ($l_hashes[$pc_id]["content"] != "" &&
4315 $r_hashes[$pc_id]["content"] != "")
4316 {
4317 $new_left = str_replace("\n", "<br />", $l_hashes[$pc_id]["content"]);
4318 $new_right = str_replace("\n", "<br />", $r_hashes[$pc_id]["content"]);
4319 $wldiff = new WordLevelDiff(array($new_left),
4320 array($new_right));
4321 $new_left = $wldiff->orig();
4322 $new_right = $wldiff->closing();
4323 $l_page->setParagraphContent($l_hashes[$pc_id]["hier_id"], $new_left[0]);
4324 $r_page->setParagraphContent($l_hashes[$pc_id]["hier_id"], $new_right[0]);
4325 }
4326 }
4327 }
4328 }
4329
4330 // determine all new paragraphs
4331 foreach ($r_hashes as $pc_id => $h)
4332 {
4333 if (!isset($l_hashes[$pc_id]))
4334 {
4335 $r_hashes[$pc_id]["change"] = "New";
4336 }
4337 }
4338 $l_page->addChangeDivClasses($l_hashes);
4339 $r_page->addChangeDivClasses($r_hashes);
4340
4341 return array("l_page" => $l_page, "r_page" => $r_page,
4342 "l_changes" => $l_hashes, "r_changes" => $r_hashes);
4343 }
4344
4349 {
4350 global $ilDB;
4351
4352 $ilDB->manipulate("UPDATE page_object ".
4353 " SET view_cnt = view_cnt + 1 ".
4354 " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
4355 " AND parent_type = ".$ilDB->quote($this->getParentType(), "text").
4356 " AND lang = ".$ilDB->quote($this->getLanguage(), "text"));
4357 }
4358
4366 static function getRecentChanges($a_parent_type, $a_parent_id, $a_period = 30, $a_lang = "")
4367 {
4368 global $ilDB;
4369
4370 $and_lang = "";
4371 if ($a_lang != "")
4372 {
4373 $and_lang = " AND lang = ".$ilDB->quote($a_lang, "text");
4374 }
4375
4376 $page_changes = array();
4377 $limit_ts = date('Y-m-d H:i:s', time() - ($a_period * 24 * 60 * 60));
4378 $q = "SELECT * FROM page_object ".
4379 " WHERE parent_id = ".$ilDB->quote($a_parent_id, "integer").
4380 " AND parent_type = ".$ilDB->quote($a_parent_type, "text").
4381 " AND last_change >= ".$ilDB->quote($limit_ts, "timestamp").$and_lang;
4382 // " AND (TO_DAYS(now()) - TO_DAYS(last_change)) <= ".((int)$a_period);
4383 $set = $ilDB->query($q);
4384 while($page = $ilDB->fetchAssoc($set))
4385 {
4386 $page_changes[] = array(
4387 "date" => $page["last_change"],
4388 "id" => $page["page_id"],
4389 "lang" => $page["lang"],
4390 "type" => "page",
4391 "user" => $page["last_change_user"]);
4392 }
4393
4394 $and_str = "";
4395 if ($a_period > 0)
4396 {
4397 $limit_ts = date('Y-m-d H:i:s', time() - ($a_period * 24 * 60 * 60));
4398 $and_str = " AND hdate >= ".$ilDB->quote($limit_ts, "timestamp")." ";
4399 }
4400
4401 $q = "SELECT * FROM page_history ".
4402 " WHERE parent_id = ".$ilDB->quote($a_parent_id, "integer").
4403 " AND parent_type = ".$ilDB->quote($a_parent_type, "text").
4404 $and_str.$and_lang;
4405 $set = $ilDB->query($q);
4406 while ($page = $ilDB->fetchAssoc($set))
4407 {
4408 $page_changes[] = array(
4409 "date" => $page["hdate"],
4410 "id" => $page["page_id"],
4411 "lang" => $page["lang"],
4412 "type" => "hist",
4413 "nr" => $page["nr"],
4414 "user" => $page["user_id"]);
4415 }
4416
4417 $page_changes = ilUtil::sortArray($page_changes, "date", "desc");
4418
4419 return $page_changes;
4420 }
4421
4429 static function getAllPages($a_parent_type, $a_parent_id, $a_lang = "-")
4430 {
4431 global $ilDB;
4432
4433 $and_lang = "";
4434 if ($a_lang != "")
4435 {
4436 $and_lang = " AND lang = ".$ilDB->quote($a_lang, "text");
4437 }
4438
4439 $page_changes = array();
4440
4441 $q = "SELECT * FROM page_object ".
4442 " WHERE parent_id = ".$ilDB->quote($a_parent_id, "integer").
4443 " AND parent_type = ".$ilDB->quote($a_parent_type, "text").$and_lang;
4444 $set = $ilDB->query($q);
4445 $pages = array();
4446 while ($page = $ilDB->fetchAssoc($set))
4447 {
4448 $key_add = ($a_lang == "")
4449 ? ":".$page["lang"]
4450 : "";
4451 $pages[$page["page_id"].$key_add] = array(
4452 "date" => $page["last_change"],
4453 "id" => $page["page_id"],
4454 "lang" => $page["lang"],
4455 "user" => $page["last_change_user"]);
4456 }
4457
4458 return $pages;
4459 }
4460
4467 static function getNewPages($a_parent_type, $a_parent_id, $a_lang = "-")
4468 {
4469 global $ilDB;
4470
4471 $and_lang = "";
4472 if ($a_lang != "")
4473 {
4474 $and_lang = " AND lang = ".$ilDB->quote($a_lang, "text");
4475 }
4476
4477 $pages = array();
4478
4479 $q = "SELECT * FROM page_object ".
4480 " WHERE parent_id = ".$ilDB->quote($a_parent_id, "integer").
4481 " AND parent_type = ".$ilDB->quote($a_parent_type, "text").$and_lang.
4482 " ORDER BY created DESC";
4483 $set = $ilDB->query($q);
4484 while($page = $ilDB->fetchAssoc($set))
4485 {
4486 if ($page["created"] != "")
4487 {
4488 $pages[] = array(
4489 "created" => $page["created"],
4490 "id" => $page["page_id"],
4491 "lang" => $page["lang"],
4492 "user" => $page["create_user"],
4493 );
4494 }
4495 }
4496
4497 return $pages;
4498 }
4499
4506 static function getParentObjectContributors($a_parent_type, $a_parent_id, $a_lang = "-")
4507 {
4508 global $ilDB;
4509
4510 $and_lang = "";
4511 if ($a_lang != "")
4512 {
4513 $and_lang = " AND lang = ".$ilDB->quote($a_lang, "text");
4514 }
4515
4516 $contributors = array();
4517 $set = $ilDB->queryF("SELECT last_change_user, lang, page_id FROM page_object ".
4518 " WHERE parent_id = %s AND parent_type = %s ".
4519 " AND last_change_user != %s".$and_lang,
4520 array("integer", "text", "integer"),
4521 array($a_parent_id, $a_parent_type, 0));
4522
4523 while ($page = $ilDB->fetchAssoc($set))
4524 {
4525 if ($a_lang == "")
4526 {
4527 $contributors[$page["last_change_user"]][$page["page_id"]][$page["lang"]] = 1;
4528 }
4529 else
4530 {
4531 $contributors[$page["last_change_user"]][$page["page_id"]] = 1;
4532 }
4533 }
4534
4535 $set = $ilDB->queryF("SELECT count(DISTINCT page_id, parent_type, hdate, lang) as cnt, lang, page_id, user_id FROM page_history ".
4536 " WHERE parent_id = %s AND parent_type = %s AND user_id != %s ".$and_lang.
4537 " GROUP BY page_id, user_id, lang ",
4538 array("integer", "text", "integer"),
4539 array($a_parent_id, $a_parent_type, 0));
4540 while ($hpage = $ilDB->fetchAssoc($set))
4541 {
4542 if ($a_lang == "")
4543 {
4544 $contributors[$hpage["user_id"]][$hpage["page_id"]][$hpage["lang"]] =
4545 $contributors[$hpage["user_id"]][$hpage["page_id"]][$hpage["lang"]] + $hpage["cnt"];
4546 }
4547 else
4548 {
4549 $contributors[$hpage["user_id"]][$hpage["page_id"]] =
4550 $contributors[$hpage["user_id"]][$hpage["page_id"]] + $hpage["cnt"];
4551 }
4552 }
4553
4554 $c = array();
4555 foreach ($contributors as $k => $co)
4556 {
4557 if (ilObject::_lookupType($k) == "usr")
4558 {
4559 $name = ilObjUser::_lookupName($k);
4560 $c[] = array("user_id" => $k, "pages" => $co,
4561 "lastname" => $name["lastname"], "firstname" => $name["firstname"]);
4562 }
4563 }
4564
4565 return $c;
4566 }
4567
4574 static function getPageContributors($a_parent_type, $a_page_id, $a_lang = "-")
4575 {
4576 global $ilDB;
4577
4578 $and_lang = "";
4579 if ($a_lang != "")
4580 {
4581 $and_lang = " AND lang = ".$ilDB->quote($a_lang, "text");
4582 }
4583
4584 $contributors = array();
4585 $set = $ilDB->queryF("SELECT last_change_user, lang FROM page_object ".
4586 " WHERE page_id = %s AND parent_type = %s ".
4587 " AND last_change_user != %s".$and_lang,
4588 array("integer", "text", "integer"),
4589 array($a_page_id, $a_parent_type, 0));
4590
4591 while ($page = $ilDB->fetchAssoc($set))
4592 {
4593 if ($a_lang == "")
4594 {
4595 $contributors[$page["last_change_user"]][$page["lang"]] = 1;
4596 }
4597 else
4598 {
4599 $contributors[$page["last_change_user"]] = 1;
4600 }
4601 }
4602
4603 $set = $ilDB->queryF("SELECT count(DISTINCT page_id, parent_type, hdate, lang) as cnt, lang, page_id, user_id FROM page_history ".
4604 " WHERE page_id = %s AND parent_type = %s AND user_id != %s ".$and_lang.
4605 " GROUP BY user_id, page_id, lang ",
4606 array("integer", "text", "integer"),
4607 array($a_page_id, $a_parent_type, 0));
4608 while ($hpage = $ilDB->fetchAssoc($set))
4609 {
4610 if ($a_lang == "")
4611 {
4612 $contributors[$hpage["user_id"]][$page["lang"]] =
4613 $contributors[$hpage["user_id"]][$page["lang"]] + $hpage["cnt"];
4614 }
4615 else
4616 {
4617 $contributors[$hpage["user_id"]] =
4618 $contributors[$hpage["user_id"]] + $hpage["cnt"];
4619 }
4620 }
4621
4622 $c = array();
4623 foreach ($contributors as $k => $co)
4624 {
4625 include_once "Services/User/classes/class.ilObjUser.php";
4626 $name = ilObjUser::_lookupName($k);
4627 $c[] = array("user_id" => $k, "pages" => $co,
4628 "lastname" => $name["lastname"], "firstname" => $name["firstname"]);
4629 }
4630
4631 return $c;
4632 }
4633
4637 function writeRenderedContent($a_content, $a_md5)
4638 {
4639 global $ilDB;
4640
4641 $ilDB->update("page_object", array(
4642 "rendered_content" => array("clob", $a_content),
4643 "render_md5" => array("text", $a_md5),
4644 "rendered_time" => array("timestamp", ilUtil::now())
4645 ), array(
4646 "page_id" => array("integer", $this->getId()),
4647 "lang" => array("text", $this->getLanguage()),
4648 "parent_type" => array("text", $this->getParentType())
4649 ));
4650 }
4651
4659 static function getPagesWithLinks($a_parent_type, $a_parent_id, $a_lang = "-")
4660 {
4661 global $ilDB;
4662
4663 $page_changes = array();
4664
4665 $and_lang = "";
4666 if ($a_lang != "")
4667 {
4668 $and_lang = " AND lang = ".$ilDB->quote($a_lang, "text");
4669 }
4670
4671 $q = "SELECT * FROM page_object ".
4672 " WHERE parent_id = ".$ilDB->quote($a_parent_id, "integer").
4673 " AND parent_type = ".$ilDB->quote($a_parent_type, "text").
4674 " AND int_links = ".$ilDB->quote(1, "integer").$and_lang;
4675 $set = $ilDB->query($q);
4676 $pages = array();
4677 while ($page = $ilDB->fetchAssoc($set))
4678 {
4679 $key_add = ($a_lang == "")
4680 ? ":".$page["lang"]
4681 : "";
4682 $pages[$page["page_id"].$key_add] = array(
4683 "date" => $page["last_change"],
4684 "id" => $page["page_id"],
4685 "lang" => $page["lang"],
4686 "user" => $page["last_change_user"]);
4687 }
4688
4689 return $pages;
4690 }
4691
4698 function containsIntLinks($a_content)
4699 {
4700 if (strpos($a_content, "IntLink"))
4701 {
4702 return true;
4703 }
4704 return false;
4705 }
4706
4711 {
4712 }
4713
4719// @todo begin: generalize
4720 function saveInitialOpenedContent($a_type, $a_id, $a_target)
4721 {
4722 $this->buildDom();
4723
4724 switch($a_type)
4725 {
4726 case "media":
4727 $link_type = "MediaObject";
4728 $a_id = "il__mob_".$a_id;
4729 break;
4730
4731 case "page":
4732 $link_type = "PageObject";
4733 $a_id = "il__pg_".$a_id;
4734 break;
4735
4736 case "term":
4737 $link_type = "GlossaryItem";
4738 $a_id = "il__git_".$a_id;
4739 $a_target = "Glossary";
4740 break;
4741 }
4742
4743 // if type or id missing -> delete InitOpenedContent, if existing
4744 if ($link_type == "" || $a_id == "")
4745 {
4746 $xpc = xpath_new_context($this->dom);
4747 $path = "//PageObject/InitOpenedContent";
4748 $res = xpath_eval($xpc, $path);
4749 if (count($res->nodeset) > 0)
4750 {
4751 $res->nodeset[0]->unlink_node($res->nodeset[0]);
4752 }
4753 }
4754 else
4755 {
4756 $xpc = xpath_new_context($this->dom);
4757 $path = "//PageObject/InitOpenedContent";
4758 $res = xpath_eval($xpc, $path);
4759 if (count($res->nodeset) > 0)
4760 {
4761 $init_node = $res->nodeset[0];
4762 $childs = $init_node->child_nodes();
4763 for($i = 0; $i < count($childs); $i++)
4764 {
4765 if ($childs[$i]->node_name() == "IntLink")
4766 {
4767 $il_node = $childs[$i];
4768 }
4769 }
4770 }
4771 else
4772 {
4773 $path = "//PageObject";
4774 $res = xpath_eval($xpc, $path);
4775 $page_node = $res->nodeset[0];
4776 $init_node = $this->dom->create_element("InitOpenedContent");
4777 $init_node = $page_node->append_child($init_node);
4778 $il_node = $this->dom->create_element("IntLink");
4779 $il_node = $init_node->append_child($il_node);
4780 }
4781 $il_node->set_attribute("Target", $a_id);
4782 $il_node->set_attribute("Type", $link_type);
4783 $il_node->set_attribute("TargetFrame", $a_target);
4784 }
4785
4786 $ret = $this->update();
4787 }
4788
4789
4796 {
4797 $this->buildDom();
4798
4799 $xpc = xpath_new_context($this->dom);
4800 $path = "//PageObject/InitOpenedContent";
4801 $res = xpath_eval($xpc, $path);
4802 $il_node = null;
4803 if (count($res->nodeset) > 0)
4804 {
4805 $init_node = $res->nodeset[0];
4806 $childs = $init_node->child_nodes();
4807 for($i = 0; $i < count($childs); $i++)
4808 {
4809 if ($childs[$i]->node_name() == "IntLink")
4810 {
4811 $il_node = $childs[$i];
4812 }
4813 }
4814 }
4815 if (!is_null($il_node))
4816 {
4817 $id = $il_node->get_attribute("Target");
4818 $link_type = $il_node->get_attribute("Type");
4819 $target = $il_node->get_attribute("TargetFrame");
4820
4821 switch($link_type)
4822 {
4823 case "MediaObject":
4824 $type = "media";
4825 break;
4826
4827 case "PageObject":
4828 $type = "page";
4829 break;
4830
4831 case "GlossaryItem":
4832 $type = "term";
4833 break;
4834 }
4835 include_once("./Services/Link/classes/class.ilInternalLink.php");
4837 return array("id" => $id, "type" => $type, "target" => $target);
4838 }
4839
4840 return array();
4841 }
4842// @todo end
4843
4854 function beforePageContentUpdate($a_page_content)
4855 {
4856
4857 }
4858
4866 function copy($a_id, $a_parent_type = "", $a_parent_id = 0, $a_clone_mobs = false)
4867 {
4868 if ($a_parent_type == "")
4869 {
4870 $a_parent_type = $this->getParentType();
4871 if ($a_parent_id == 0)
4872 {
4873 $a_parent_id = $this->getParentId();
4874 }
4875 }
4876
4877 include_once("./Services/COPage/classes/class.ilPageObjectFactory.php");
4878 foreach (self::lookupTranslations($this->getParentType(), $this->getId()) as $l)
4879 {
4880 $existed = false;
4881 $orig_page = ilPageObjectFactory::getInstance($this->getParentType(), $this->getId(), 0, $l);
4882 if (ilPageObject::_exists($a_parent_type, $a_id, $l))
4883 {
4884 $new_page_object = ilPageObjectFactory::getInstance($a_parent_type, $a_id, 0, $l);
4885 $existed = true;
4886 }
4887 else
4888 {
4889 $new_page_object = ilPageObjectFactory::getInstance($a_parent_type, 0, 0, $l);
4890 $new_page_object->setParentId($a_parent_id);
4891 $new_page_object->setId($a_id);
4892 }
4893 $new_page_object->setXMLContent($orig_page->copyXMLContent($a_clone_mobs));
4894 $new_page_object->setActive($orig_page->getActive());
4895 $new_page_object->setActivationStart($orig_page->getActivationStart());
4896 $new_page_object->setActivationEnd($orig_page->getActivationEnd());
4897 if ($existed)
4898 {
4899 $new_page_object->buildDom();
4900 $new_page_object->update();
4901 }
4902 else
4903 {
4904 $new_page_object->create();
4905 }
4906 }
4907
4908 }
4909
4917 static function lookupTranslations($a_parent_type, $a_id)
4918 {
4919 global $ilDB;
4920
4921 $set = $ilDB->query("SELECT lang FROM page_object ".
4922 " WHERE page_id = ".$ilDB->quote($a_id, "integer").
4923 " AND parent_type = ".$ilDB->quote($a_parent_type, "text")
4924 );
4925 $langs = array();
4926 while ($rec = $ilDB->fetchAssoc($set))
4927 {
4928 $langs[] = $rec["lang"];
4929 }
4930 return $langs;
4931 }
4932
4933
4939 function copyPageToTranslation($a_target_lang)
4940 {
4941 $transl_page = ilPageObjectFactory::getInstance($this->getParentType(),
4942 0, 0, $a_target_lang);
4943 $transl_page->setId($this->getId());
4944 $transl_page->setParentId($this->getParentId());
4945 $transl_page->setXMLContent($this->copyXMLContent());
4946 $transl_page->setActive($this->getActive());
4947 $transl_page->setActivationStart($this->getActivationStart());
4948 $transl_page->setActivationEnd($this->getActivationEnd());
4949 $transl_page->create();
4950 }
4951
4955
4959 function getEditLock()
4960 {
4961 global $ilUser, $ilDB;
4962 //return false;
4963 $aset = new ilSetting("adve");
4964
4965 $min = (int) $aset->get("block_mode_minutes") ;
4966 if ($min > 0)
4967 {
4968 // try to set the lock for the user
4969 $ts = time();
4970 $ilDB->manipulate("UPDATE page_object SET ".
4971 " edit_lock_user = ".$ilDB->quote($ilUser->getId(), "integer").",".
4972 " edit_lock_ts = ".$ilDB->quote($ts, "integer").
4973 " WHERE (edit_lock_user = ".$ilDB->quote($ilUser->getId(), "integer")." OR ".
4974 " edit_lock_ts < ".$ilDB->quote(time() - ($min * 60), "integer").") ".
4975 " AND page_id = ".$ilDB->quote($this->getId(), "integer").
4976 " AND parent_type = ".$ilDB->quote($this->getParentType(), "text")
4977 );
4978
4979 $set = $ilDB->query("SELECT edit_lock_user FROM page_object ".
4980 " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
4981 " AND parent_type = ".$ilDB->quote($this->getParentType(), "text")
4982 );
4983 $rec = $ilDB->fetchAssoc($set);
4984 if ($rec["edit_lock_user"] != $ilUser->getId())
4985 {
4986 return false;
4987 }
4988 }
4989
4990 return true;
4991 }
4992
4997 {
4998 global $ilUser, $ilDB;
4999
5000 $aset = new ilSetting("adve");
5001
5002 $min = (int) $aset->get("block_mode_minutes") ;
5003 if ($min > 0)
5004 {
5005 // try to set the lock for the user
5006 $ts = time();
5007 $ilDB->manipulate("UPDATE page_object SET ".
5008 " edit_lock_user = ".$ilDB->quote($ilUser->getId(), "integer").",".
5009 " edit_lock_ts = 0".
5010 " WHERE edit_lock_user = ".$ilDB->quote($ilUser->getId(), "integer").
5011 " AND page_id = ".$ilDB->quote($this->getId(), "integer").
5012 " AND parent_type = ".$ilDB->quote($this->getParentType(), "text")
5013 );
5014
5015 $set = $ilDB->query("SELECT edit_lock_user FROM page_object ".
5016 " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
5017 " AND parent_type = ".$ilDB->quote($this->getParentType(), "text")
5018 );
5019 $rec = $ilDB->fetchAssoc($set);
5020 if ($rec["edit_lock_user"] != $ilUser->getId())
5021 {
5022 return false;
5023 }
5024 }
5025
5026 return true;
5027 }
5028
5035 {
5036 global $ilDB;
5037
5038 $aset = new ilSetting("adve");
5039 $min = (int) $aset->get("block_mode_minutes");
5040
5041 $set = $ilDB->query("SELECT edit_lock_user, edit_lock_ts FROM page_object ".
5042 " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
5043 " AND parent_type = ".$ilDB->quote($this->getParentType(), "text")
5044 );
5045 $rec = $ilDB->fetchAssoc($set);
5046 $rec["edit_lock_until"] = $rec["edit_lock_ts"] + $min * 60;
5047
5048 return $rec;
5049 }
5050
5063 public static function truncateHTML($a_text, $a_length = 100, $a_ending = '...', $a_exact = false, $a_consider_html = true)
5064 {
5065 include_once "Services/Utilities/classes/class.ilStr.php";
5066
5067 if ($a_consider_html)
5068 {
5069 // if the plain text is shorter than the maximum length, return the whole text
5070 if(strlen(preg_replace('/<.*?>/', '', $a_text)) <= $a_length)
5071 {
5072 return $a_text;
5073 }
5074
5075 // splits all html-tags to scanable lines
5076 $total_length = strlen($a_ending);
5077 $open_tags = array();
5078 $truncate = '';
5079 preg_match_all('/(<.+?>)?([^<>]*)/s', $a_text, $lines, PREG_SET_ORDER);
5080 foreach($lines as $line_matchings)
5081 {
5082 // if there is any html-tag in this line, handle it and add it (uncounted) to the output
5083 if(!empty($line_matchings[1]))
5084 {
5085 // if it's an "empty element" with or without xhtml-conform closing slash
5086 if(preg_match('/^<(\s*.+?\/\s*|\s*(img|br|input|hr|area|base|basefont|col|frame|isindex|link|meta|param)(\s.+?)?)>$/is', $line_matchings[1]))
5087 {
5088 // do nothing
5089 }
5090 // if tag is a closing tag
5091 else if(preg_match('/^<\s*\/([^\s]+?)\s*>$/s', $line_matchings[1], $tag_matchings))
5092 {
5093 // delete tag from $open_tags list
5094 $pos = array_search($tag_matchings[1], $open_tags);
5095 if ($pos !== false)
5096 {
5097 unset($open_tags[$pos]);
5098 }
5099 }
5100 // if tag is an opening tag
5101 else if (preg_match('/^<\s*([^\s>!]+).*?>$/s', $line_matchings[1], $tag_matchings))
5102 {
5103 // add tag to the beginning of $open_tags list
5104 array_unshift($open_tags, strtolower($tag_matchings[1]));
5105 }
5106 // add html-tag to $truncate'd text
5107 $truncate .= $line_matchings[1];
5108 }
5109
5110 // calculate the length of the plain text part of the line; handle entities as one character
5111 $content_length = strlen(preg_replace('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|[0-9a-f]{1,6};/i', ' ', $line_matchings[2]));
5112 if($total_length+$content_length > $a_length)
5113 {
5114 // the number of characters which are left
5115 $left = $a_length - $total_length;
5116 $entities_length = 0;
5117 // search for html entities
5118 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))
5119 {
5120 // calculate the real length of all entities in the legal range
5121 foreach($entities[0] as $entity)
5122 {
5123 if($entity[1]+1-$entities_length <= $left)
5124 {
5125 $left--;
5126 $entities_length += strlen($entity[0]);
5127 }
5128 else
5129 {
5130 // no more characters left
5131 break;
5132 }
5133 }
5134 }
5135
5136 // $truncate .= substr($line_matchings[2], 0, $left+$entities_length);
5137 $truncate .= ilStr::shortenText($line_matchings[2], 0, $left+$entities_length);
5138
5139 // maximum lenght is reached, so get off the loop
5140 break;
5141 }
5142 else
5143 {
5144 $truncate .= $line_matchings[2];
5145 $total_length += $content_length;
5146 }
5147
5148 // if the maximum length is reached, get off the loop
5149 if($total_length >= $a_length)
5150 {
5151 break;
5152 }
5153 }
5154 }
5155 else
5156 {
5157 if(strlen($a_text) <= $a_length)
5158 {
5159 return $a_text;
5160 }
5161 else
5162 {
5163 // $truncate = substr($a_text, 0, $a_length - strlen($a_ending));
5164 $truncate = ilStr::shortenText($a_text, 0, $a_length - strlen($a_ending));
5165 }
5166 }
5167
5168 // THIS IS BUGGY AS IT MIGHT BREAK AN OPEN TAG AT THE END
5169 if(!sizeof($open_tags))
5170 {
5171 // if the words shouldn't be cut in the middle...
5172 if (!$a_exact)
5173 {
5174 // ...search the last occurance of a space...
5175 $spacepos = strrpos($truncate, ' ');
5176 if($spacepos !== false)
5177 {
5178 // ...and cut the text in this position
5179 // $truncate = substr($truncate, 0, $spacepos);
5180 $truncate = ilStr::shortenText($truncate, 0, $spacepos);
5181 }
5182 }
5183 }
5184
5185 // add the defined ending to the text
5186 $truncate .= $a_ending;
5187
5188 if($a_consider_html)
5189 {
5190 // close all unclosed html-tags
5191 foreach($open_tags as $tag)
5192 {
5193 $truncate .= '</'.$tag.'>';
5194 }
5195 }
5196
5197 return $truncate;
5198 }
5199
5206 {
5207 return array();
5208 }
5209
5217 static function getLastChangeByParent($a_parent_type, $a_parent_id, $a_lang = "")
5218 {
5219 global $ilDB;
5220
5221 $and_lang = "";
5222 if ($a_lang != "")
5223 {
5224 $and_lang = " AND lang = ".$ilDB->quote($a_lang, "text");
5225 }
5226
5227 $ilDB->setLimit(1);
5228 $q = "SELECT last_change FROM page_object ".
5229 " WHERE parent_id = ".$ilDB->quote($a_parent_id, "integer").
5230 " AND parent_type = ".$ilDB->quote($a_parent_type, "text").$and_lang.
5231 " ORDER BY last_change DESC";
5232
5233 $set = $ilDB->query($q);
5234 $rec = $ilDB->fetchAssoc($set);
5235
5236 return $rec["last_change"];
5237 }
5238
5245 {
5246 $file_obj_ids = array();
5247
5248 // insert inst id file item identifier entries
5249 $xpc = xpath_new_context($this->dom);
5250 $path = "//FileItem/Identifier";
5251 $res = xpath_eval($xpc, $path);
5252 for($i = 0; $i < count($res->nodeset); $i++)
5253 {
5254 $file_obj_ids[] = $res->nodeset[$i]->get_attribute("Entry");
5255 }
5256 unset($xpc);
5257 return $file_obj_ids;
5258 }
5259
5260
5261
5262
5263}
5264?>
$size
Definition: RandomTest.php:79
global $l
Definition: afr.php:30
$filename
Definition: buildRTE.php:89
$_GET["client_id"]
const DB_FETCHMODE_ASSOC
Definition: class.ilDB.php:10
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)
getPCDefinitions()
Get PC definitions.
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 _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.
_resolveMapAreaLinks($a_mob_id)
resolve internal links of all media items of a media object
_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.
_deleteAllUsages($a_type, $a_id, $a_usage_hist_nr=0, $a_lang="-")
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)
_getLastUpdateOfObjects($a_objs)
Get last update for a set of media objects.
static _exists($a_id, $a_reference=false, $a_type=null)
checks if an object exists in object_data@access public
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.
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.
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.
initPageConfig()
Init page config.
read()
Read page data.
getLastChangeUser()
Get last change user.
_moveContentAfterHierId(&$a_source_page, &$a_target_page, $a_hid)
move content of hierarchical id >= $a_hid to other page
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 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
static getPagesWithLinks($a_parent_type, $a_parent_id, $a_lang="-")
Get all pages for parent object that contain internal links.
_writeParentId($a_parent_type, $a_pg_id, $a_par_id)
Write parent id.
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.
_writeActive($a_id, $a_parent_type, $a_active, $a_reset_scheduled_activation=true, $a_lang="-")
write activation status
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
ilPageObject($a_id=0, $a_old_nr=0, $a_lang="-")
Constructor @access public.
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).
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)
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.
_lookupActivationData($a_id, $a_parent_type, $a_lang="-")
Lookup activation data.
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.
_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.
$_POST['username']
Definition: cron.php:12
const DOMXML_LOAD_VALIDATING
const DOMXML_LOAD_PARSING
$h
$params
Definition: example_049.php:96
$target_arr
Definition: goto.php:86
global $ilCtrl
Definition: ilias.php:18
const ILIAS_VERSION_NUMERIC
xslt_free(&$proc)
xslt_create()
domxml_open_mem($str, $mode=DOMXML_LOAD_PARSING, &$error=NULL)
xpath_eval($xpath_context, $eval_str, $contextnode=null)
xpath_new_context($dom_document)
exit
Definition: login.php:54
redirection script todo: (a better solution should control the processing via a xml file)
global $lng
Definition: privfeed.php:40
$ref_id
Definition: sahs_server.php:39
$path
Definition: index.php:22
global $ilDB
$lm_set
$errors
$mobs
global $ilUser
Definition: imgupload.php:15