ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
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{
51 protected $obj_definition;
52
53 public static $exists = array();
54
58 protected $db;
59
63 protected $user;
64
68 protected $lng;
69
73 protected $tree;
74
78 protected $id;
79 public $dom;
80 public $xml;
81 public $encoding;
82 public $node;
83 public $cur_dtd = "ilias_pg_5_3.dtd";
87 public $parent_id;
93
97 protected $language = "-";
98
102 protected static $activation_data = array();
103
107 protected $import_mode = false;
108
112 protected $log;
113
117 protected $page_record = array();
118
122 protected $active = false;
123
127 protected $page_config;
128
133 final public function __construct($a_id = 0, $a_old_nr = 0, $a_lang = "-")
134 {
135 global $DIC;
136 $this->obj_definition = $DIC["objDefinition"];
137 $this->db = $DIC->database();
138 $this->user = $DIC->user();
139 $this->lng = $DIC->language();
140 $this->tree = $DIC->repositoryTree();
141 $this->log = ilLoggerFactory::getLogger('copg');
142
143 // @todo: move this elsewhere
144 // require_once("./Services/COPage/syntax_highlight/php/Beautifier/Init.php");
145 // require_once("./Services/COPage/syntax_highlight/php/Output/Output_css.php");
146
147 $this->parent_type = $this->getParentType();
148 $this->id = $a_id;
149 $this->setLanguage($a_lang);
150
151 $this->contains_int_link = false;
152 $this->needs_parsing = false;
153 $this->update_listeners = array();
154 $this->update_listener_cnt = 0;
155 $this->dom_builded = false;
156 $this->page_not_found = false;
157 $this->old_nr = $a_old_nr;
158 $this->encoding = "UTF-8";
159 $this->id_elements =
160 array("PageContent", "TableRow", "TableData", "ListItem", "FileItem",
161 "Section", "Tab", "ContentPopup", "GridCell");
162 $this->setActive(true);
163 $this->show_page_act_info = false;
164
165 if ($a_id != 0) {
166 $this->read();
167 }
168
169 $this->initPageConfig();
170
171 $this->afterConstructor();
172 }
173
177 public function afterConstructor()
178 {
179 }
180
181
187 abstract public function getParentType();
188
189
193 final public function initPageConfig()
194 {
195 include_once("./Services/COPage/classes/class.ilPageObjectFactory.php");
197 $this->setPageConfig($cfg);
198 }
199
205 public function setLanguage($a_val)
206 {
207 $this->language = $a_val;
208 }
209
215 public function getLanguage()
216 {
217 return $this->language;
218 }
219
225 public function setPageConfig($a_val)
226 {
227 $this->page_config = $a_val;
228 }
229
235 public function getPageConfig()
236 {
237 return $this->page_config;
238 }
239
245 public function setRenderMd5($a_rendermd5)
246 {
247 $this->rendermd5 = $a_rendermd5;
248 }
249
255 public function getRenderMd5()
256 {
257 return $this->rendermd5;
258 }
259
265 public function setRenderedContent($a_renderedcontent)
266 {
267 $this->renderedcontent = $a_renderedcontent;
268 }
269
275 public function getRenderedContent()
276 {
277 return $this->renderedcontent;
278 }
279
285 public function setRenderedTime($a_renderedtime)
286 {
287 $this->renderedtime = $a_renderedtime;
288 }
289
295 public function getRenderedTime()
296 {
297 return $this->renderedtime;
298 }
299
305 public function setLastChange($a_lastchange)
306 {
307 $this->lastchange = $a_lastchange;
308 }
309
315 public function getLastChange()
316 {
317 return $this->lastchange;
318 }
319
325 public function setLastChangeUser($a_val)
326 {
327 $this->last_change_user = $a_val;
328 }
329
335 public function getLastChangeUser()
336 {
337 return $this->last_change_user;
338 }
339
345 public function setShowActivationInfo($a_val)
346 {
347 $this->show_page_act_info = $a_val;
348 }
349
355 public function getShowActivationInfo()
356 {
357 return $this->show_page_act_info;
358 }
359
363 public function read()
364 {
365 $this->setActive(true);
366 if ($this->old_nr == 0) {
367 $query = "SELECT * FROM page_object" .
368 " WHERE page_id = " . $this->db->quote($this->id, "integer") .
369 " AND parent_type=" . $this->db->quote($this->getParentType(), "text") .
370 " AND lang = " . $this->db->quote($this->getLanguage(), "text");
371 $pg_set = $this->db->query($query);
372 $this->page_record = $this->db->fetchAssoc($pg_set);
373 $this->setActive($this->page_record["active"]);
374 $this->setActivationStart($this->page_record["activation_start"]);
375 $this->setActivationEnd($this->page_record["activation_end"]);
376 $this->setShowActivationInfo($this->page_record["show_activation_info"]);
377 } else {
378 $query = "SELECT * FROM page_history" .
379 " WHERE page_id = " . $this->db->quote($this->id, "integer") .
380 " AND parent_type=" . $this->db->quote($this->getParentType(), "text") .
381 " AND nr = " . $this->db->quote((int) $this->old_nr, "integer") .
382 " AND lang = " . $this->db->quote($this->getLanguage(), "text");
383 $pg_set = $this->db->query($query);
384 $this->page_record = $this->db->fetchAssoc($pg_set);
385 }
386 if (!$this->page_record) {
387 include_once("./Services/COPage/exceptions/class.ilCOPageNotFoundException.php");
388 throw new ilCOPageNotFoundException("Error: Page " . $this->id . " is not in database" .
389 " (parent type " . $this->getParentType() . ", lang: " . $this->getLanguage() . ").");
390 }
391
392 $this->xml = $this->page_record["content"];
393 $this->setParentId($this->page_record["parent_id"]);
394 $this->last_change_user = $this->page_record["last_change_user"];
395 $this->create_user = $this->page_record["create_user"];
396 $this->setRenderedContent($this->page_record["rendered_content"]);
397 $this->setRenderMd5($this->page_record["render_md5"]);
398 $this->setRenderedTime($this->page_record["rendered_time"]);
399 $this->setLastChange($this->page_record["last_change"]);
400 }
401
409 public static function _exists($a_parent_type, $a_id, $a_lang = "", $a_no_cache = false)
410 {
411 global $DIC;
412
413 $db = $DIC->database();
414
415 if (!$a_no_cache && isset(self::$exists[$a_parent_type . ":" . $a_id . ":" . $a_lang])) {
416 return self::$exists[$a_parent_type . ":" . $a_id . ":" . $a_lang];
417 }
418
419 $and_lang = "";
420 if ($a_lang != "") {
421 $and_lang = " AND lang = " . $db->quote($a_lang, "text");
422 }
423
424 $query = "SELECT page_id FROM page_object WHERE page_id = " . $db->quote($a_id, "integer") . " " .
425 "AND parent_type = " . $db->quote($a_parent_type, "text") . $and_lang;
426 $set = $db->query($query);
427 if ($row = $db->fetchAssoc($set)) {
428 self::$exists[$a_parent_type . ":" . $a_id . ":" . $a_lang] = true;
429 return true;
430 } else {
431 self::$exists[$a_parent_type . ":" . $a_id . ":" . $a_lang] = false;
432 return false;
433 }
434 }
435
443 public static function _existsAndNotEmpty($a_parent_type, $a_id, $a_lang = "-")
444 {
445 include_once("./Services/COPage/classes/class.ilPageUtil.php");
446 return ilPageUtil::_existsAndNotEmpty($a_parent_type, $a_id, $a_lang);
447 }
448
449 public function buildDom($a_force = false)
450 {
451 if ($this->dom_builded && !$a_force) {
452 return;
453 }
454
455 //echo "\n<br>buildDomWith:".$this->getId().":xml:".$this->getXMLContent(true).":<br>";
456
457 $options = 0;
458 //$options = DOMXML_LOAD_VALIDATING;
459 //$options = LIBXML_DTDLOAD;
460 //$options = LIBXML_NOXMLDECL;
461 //echo htmlentities($this->getXMLContent(true))."<br>";
462 $this->dom = @domxml_open_mem($this->getXMLContent(true), $options, $error);
463 //var_dump($error);
464 $xpc = xpath_new_context($this->dom);
465 $path = "//PageObject";
466 $res = xpath_eval($xpc, $path);
467 if (count($res->nodeset) == 1) {
468 // echo "h";
469 $this->node = $res->nodeset[0];
470 }
471 //echo htmlentities($this->dom->dump_node($this->node)); exit;
472
473 if (empty($error)) {
474 $this->dom_builded = true;
475 return true;
476 } else {
477 return $error;
478 }
479 }
480
481 public function freeDom()
482 {
483 //$this->dom->free();
484 unset($this->dom);
485 }
486
490 public function getDom()
491 {
492 return $this->dom;
493 }
494
501 public function getDomDoc()
502 {
503 if ($this->dom instanceof php4DOMDocument) {
504 return $this->dom->myDOMDocument;
505 }
506
507 return $this->dom;
508 }
509
510
514 public function setId($a_id)
515 {
516 $this->id = $a_id;
517 }
518
519 public function getId()
520 {
521 return $this->id;
522 }
523
524 public function setParentId($a_id)
525 {
526 $this->parent_id = $a_id;
527 }
528
529 public function getParentId()
530 {
531 return $this->parent_id;
532 }
533
534 public function addUpdateListener(&$a_object, $a_method, $a_parameters = "")
535 {
537 $this->update_listeners[$cnt]["object"] = $a_object;
538 $this->update_listeners[$cnt]["method"] = $a_method;
539 $this->update_listeners[$cnt]["parameters"] = $a_parameters;
540 $this->update_listener_cnt++;
541 }
542
543 public function callUpdateListeners()
544 {
545 for ($i=0; $i<$this->update_listener_cnt; $i++) {
546 $object = $this->update_listeners[$i]["object"];
547 $method = $this->update_listeners[$i]["method"];
548 $parameters = $this->update_listeners[$i]["parameters"];
549 $object->$method($parameters);
550 }
551 }
552
558 public function setActive($a_active)
559 {
560 $this->active = $a_active;
561 }
562
568 public function getActive($a_check_scheduled_activation = false)
569 {
570 if ($a_check_scheduled_activation && !$this->active) {
571 include_once("./Services/Calendar/classes/class.ilDateTime.php");
572 $start = new ilDateTime($this->getActivationStart(), IL_CAL_DATETIME);
574 $now = new ilDateTime(time(), IL_CAL_UNIX);
575 if (!ilDateTime::_before($now, $start) && !ilDateTime::_after($now, $end)) {
576 return true;
577 }
578 }
579 return $this->active;
580 }
581
587 public static function preloadActivationDataByParentId($a_parent_id)
588 {
589 global $DIC;
590
591 $db = $DIC->database();
592 $set = $db->query(
593 "SELECT page_id, parent_type, lang, active, activation_start, activation_end, show_activation_info FROM page_object " .
594 " WHERE parent_id = " . $db->quote($a_parent_id, "integer")
595 );
596 while ($rec = $db->fetchAssoc($set)) {
597 self::$activation_data[$rec["page_id"] . ":" . $rec["parent_type"] . ":" . $rec["lang"]] = $rec;
598 }
599 }
600
601
605 public static function _lookupActive($a_id, $a_parent_type, $a_check_scheduled_activation = false, $a_lang = "-")
606 {
607 global $DIC;
608
609 $db = $DIC->database();
610
611 // language must be set at least to "-"
612 if ($a_lang == "") {
613 $a_lang = "-";
614 }
615
616 if (isset(self::$activation_data[$a_id . ":" . $a_parent_type . ":" . $a_lang])) {
617 $rec = self::$activation_data[$a_id . ":" . $a_parent_type . ":" . $a_lang];
618 } else {
619 $set = $db->queryF(
620 "SELECT active, activation_start, activation_end FROM page_object WHERE page_id = %s" .
621 " AND parent_type = %s AND lang = %s",
622 array("integer", "text", "text"),
623 array($a_id, $a_parent_type, $a_lang)
624 );
625 $rec = $db->fetchAssoc($set);
626 }
627
628
629 $rec["n"] = ilUtil::now();
630
631 if (!$rec["active"] && $a_check_scheduled_activation) {
632 if ($rec["n"] >= $rec["activation_start"] &&
633 $rec["n"] <= $rec["activation_end"]) {
634 return true;
635 }
636 }
637
638 return $rec["active"];
639 }
640
644 public static function _isScheduledActivation($a_id, $a_parent_type, $a_lang = "-")
645 {
646 global $DIC;
647
648 $db = $DIC->database();
649
650 // language must be set at least to "-"
651 if ($a_lang == "") {
652 $a_lang = "-";
653 }
654
655 //echo "<br>";
656 //var_dump(self::$activation_data); exit;
657 if (isset(self::$activation_data[$a_id . ":" . $a_parent_type . ":" . $a_lang])) {
658 $rec = self::$activation_data[$a_id . ":" . $a_parent_type . ":" . $a_lang];
659 } else {
660 $set = $db->queryF(
661 "SELECT active, activation_start, activation_end FROM page_object WHERE page_id = %s" .
662 " AND parent_type = %s AND lang = %s",
663 array("integer", "text", "text"),
664 array($a_id, $a_parent_type, $a_lang)
665 );
666 $rec = $db->fetchAssoc($set);
667 }
668
669 if (!$rec["active"] && $rec["activation_start"] != "") {
670 return true;
671 }
672
673 return false;
674 }
675
679 public static function _writeActive($a_id, $a_parent_type, $a_active, $a_reset_scheduled_activation = true, $a_lang = "-")
680 {
681 global $DIC;
682
683 $db = $DIC->database();
684
685 // language must be set at least to "-"
686 if ($a_lang == "") {
687 $a_lang = "-";
688 }
689
690 if ($a_reset_scheduled_activation) {
691 $st = $db->manipulateF(
692 "UPDATE page_object SET active = %s, activation_start = %s, " .
693 " activation_end = %s WHERE page_id = %s" .
694 " AND parent_type = %s AND lang = %s",
695 array("boolean", "timestamp", "timestamp", "integer", "text", "text"),
696 array($a_active, null, null, $a_id, $a_parent_type, $a_lang)
697 );
698 } else {
699 $st = $db->prepareManip(
700 "UPDATE page_object SET active = %s WHERE page_id = %s" .
701 " AND parent_type = %s AND lang = %s",
702 array("boolean", "integer", "text", "text"),
703 array($a_active, $a_id, $a_parent_type, $a_lang)
704 );
705 }
706 }
707
711 public static function _lookupActivationData($a_id, $a_parent_type, $a_lang = "-")
712 {
713 global $DIC;
714
715 $db = $DIC->database();
716
717 // language must be set at least to "-"
718 if ($a_lang == "") {
719 $a_lang = "-";
720 }
721
722 if (isset(self::$activation_data[$a_id . ":" . $a_parent_type . ":" . $a_lang])) {
723 $rec = self::$activation_data[$a_id . ":" . $a_parent_type . ":" . $a_lang];
724 } else {
725 $set = $db->queryF(
726 "SELECT active, activation_start, activation_end, show_activation_info FROM page_object WHERE page_id = %s" .
727 " AND parent_type = %s AND lang = %s",
728 array("integer", "text", "text"),
729 array($a_id, $a_parent_type, $a_lang)
730 );
731 $rec = $db->fetchAssoc($set);
732 }
733
734 return $rec;
735 }
736
737
741 public static function lookupParentId($a_id, $a_type)
742 {
743 global $DIC;
744
745 $db = $DIC->database();
746
747 $res = $db->query("SELECT parent_id FROM page_object WHERE page_id = " . $db->quote($a_id, "integer") . " " .
748 "AND parent_type=" . $db->quote($a_type, "text"));
749 $rec = $db->fetchAssoc($res);
750 return $rec["parent_id"];
751 }
752
756 public static function _writeParentId($a_parent_type, $a_pg_id, $a_par_id)
757 {
758 global $DIC;
759
760 $db = $DIC->database();
761 $db->manipulateF(
762 "UPDATE page_object SET parent_id = %s WHERE page_id = %s" .
763 " AND parent_type = %s",
764 array("integer", "integer", "text"),
765 array($a_par_id, $a_pg_id, $a_parent_type)
766 );
767 }
768
774 public function setActivationStart($a_activationstart)
775 {
776 if ($a_activationstart == "") {
777 $a_activationstart = null;
778 }
779 $this->activationstart = $a_activationstart;
780 }
781
787 public function getActivationStart()
788 {
789 return $this->activationstart;
790 }
791
797 public function setActivationEnd($a_activationend)
798 {
799 if ($a_activationend == "") {
800 $a_activationend = null;
801 }
802 $this->activationend = $a_activationend;
803 }
804
810 public function getActivationEnd()
811 {
812 return $this->activationend;
813 }
814
823 public function getContentObject($a_hier_id, $a_pc_id = "")
824 {
825 $cont_node = $this->getContentNode($a_hier_id, $a_pc_id);
826 if (!is_object($cont_node)) {
827 return false;
828 }
829 include_once("./Services/COPage/classes/class.ilCOPagePCDef.php");
830 $node_name = $cont_node->node_name();
831 if ($node_name == "PageObject") {
832 return null;
833 }
834 if ($node_name == "PageContent") {
835 $child_node = $cont_node->first_child();
836 $node_name = $child_node->node_name();
837 }
838
839 // table extra handling (@todo: get rid of it)
840 if ($node_name == "Table") {
841 if ($child_node->get_attribute("DataTable") == "y") {
842 require_once("./Services/COPage/classes/class.ilPCDataTable.php");
843 $tab = new ilPCDataTable($this);
844 $tab->setNode($cont_node);
845 $tab->setHierId($a_hier_id);
846 } else {
847 require_once("./Services/COPage/classes/class.ilPCTable.php");
848 $tab = new ilPCTable($this);
849 $tab->setNode($cont_node);
850 $tab->setHierId($a_hier_id);
851 }
852 $tab->setPcId($a_pc_id);
853 return $tab;
854 }
855
856 // media extra handling (@todo: get rid of it)
857 if ($node_name == "MediaObject") {
858 if ($_GET["pgEdMediaMode"] != "") {
859 echo "ilPageObject::error media";
860 exit;
861 }
862
863 //require_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
864 require_once("./Services/COPage/classes/class.ilPCMediaObject.php");
865
866 $mal_node = $child_node->first_child();
867 //echo "ilPageObject::getContentObject:nodename:".$mal_node->node_name().":<br>";
868 $id_arr = explode("_", $mal_node->get_attribute("OriginId"));
869 $mob_id = $id_arr[count($id_arr) - 1];
870
871 // allow deletion of non-existing media objects
872 if (!ilObject::_exists($mob_id) && in_array("delete", $_POST)) {
873 $mob_id = 0;
874 }
875
876 //$mob = new ilObjMediaObject($mob_id);
877 $mob = new ilPCMediaObject($this);
878 $mob->readMediaObject($mob_id);
879
880 //$mob->setDom($this->dom);
881 $mob->setNode($cont_node);
882 $mob->setHierId($a_hier_id);
883 $mob->setPcId($a_pc_id);
884 return $mob;
885 }
886
887 //
888 // generic procedure
889 //
890
891 $pc_def = ilCOPagePCDef::getPCDefinitionByName($node_name);
892
893 // check if pc definition has been found
894 if (!is_array($pc_def)) {
895 include_once("./Services/COPage/exceptions/class.ilCOPageUnknownPCTypeException.php");
896 throw new ilCOPageUnknownPCTypeException('Unknown PC Name "' . $node_name . '".');
897 }
898 $pc_class = "ilPC" . $pc_def["name"];
899 $pc_path = "./" . $pc_def["component"] . "/" . $pc_def["directory"] . "/class." . $pc_class . ".php";
900 require_once($pc_path);
901 $pc = new $pc_class($this);
902 $pc->setNode($cont_node);
903 $pc->setHierId($a_hier_id);
904 $pc->setPcId($a_pc_id);
905 return $pc;
906 }
907
914 public function &getContentNode($a_hier_id, $a_pc_id = "")
915 {
916 $xpc = xpath_new_context($this->dom);
917 if ($a_hier_id == "pg") {
918 return $this->node;
919 } else {
920 // get per pc id
921 if ($a_pc_id != "") {
922 $path = "//*[@PCID = '$a_pc_id']";
923 $res = xpath_eval($xpc, $path);
924 if (count($res->nodeset) == 1) {
925 $cont_node = $res->nodeset[0];
926 return $cont_node;
927 }
928 }
929
930 // fall back to hier id
931 $path = "//*[@HierId = '$a_hier_id']";
932 $res = xpath_eval($xpc, $path);
933 if (count($res->nodeset) == 1) {
934 $cont_node = $res->nodeset[0];
935 return $cont_node;
936 }
937 }
938 }
939
946 public function checkForTag($a_content_tag, $a_hier_id, $a_pc_id = "")
947 {
948 $xpc = xpath_new_context($this->dom);
949 // get per pc id
950 if ($a_pc_id != "") {
951 $path = "//*[@PCID = '$a_pc_id']//" . $a_content_tag;
952 $res = xpath_eval($xpc, $path);
953 if (count($res->nodeset) > 0) {
954 return true;
955 }
956 }
957
958 // fall back to hier id
959 $path = "//*[@HierId = '$a_hier_id']//" . $a_content_tag;
960 $res = xpath_eval($xpc, $path);
961 if (count($res->nodeset) > 0) {
962 return true;
963 }
964 return false;
965 }
966
967 // only for test purposes
968 public function lookforhier($a_hier_id)
969 {
970 $xpc = xpath_new_context($this->dom);
971 $path = "//*[@HierId = '$a_hier_id']";
972 $res = xpath_eval($xpc, $path);
973 if (count($res->nodeset) == 1) {
974 return "YES";
975 } else {
976 return "NO";
977 }
978 }
979
980
981 public function &getNode()
982 {
983 return $this->node;
984 }
985
986
995 public function setXMLContent($a_xml, $a_encoding = "UTF-8")
996 {
997 $this->encoding = $a_encoding;
998 $this->xml = $a_xml;
999 }
1000
1007 public function appendXMLContent($a_xml)
1008 {
1009 $this->xml.= $a_xml;
1010 }
1011
1012
1016 public function getXMLContent($a_incl_head = false)
1017 {
1018 // build full http path for XML DOCTYPE header.
1019 // Under windows a relative path doesn't work :-(
1020 if ($a_incl_head) {
1021 //echo "+".$this->encoding."+";
1022 $enc_str = (!empty($this->encoding))
1023 ? "encoding=\"" . $this->encoding . "\""
1024 : "";
1025 return "<?xml version=\"1.0\" $enc_str ?>" .
1026 "<!DOCTYPE PageObject SYSTEM \"" . ILIAS_ABSOLUTE_PATH . "/xml/" . $this->cur_dtd . "\">" .
1027 $this->xml;
1028 } else {
1029 return $this->xml;
1030 }
1031 }
1032
1037 public function copyXmlContent($a_clone_mobs = false)
1038 {
1039 $xml = $this->getXmlContent();
1040 $temp_dom = domxml_open_mem(
1041 '<?xml version="1.0" encoding="UTF-8"?>' . $xml,
1043 $error
1044 );
1045 if (empty($error)) {
1046 $this->handleCopiedContent($temp_dom, true, $a_clone_mobs);
1047 }
1048 $xml = $temp_dom->dump_mem(0, $this->encoding);
1049 $xml = preg_replace('/<\?xml[^>]*>/i', "", $xml);
1050 $xml = preg_replace('/<!DOCTYPE[^>]*>/i', "", $xml);
1051
1052 return $xml;
1053 }
1054
1055 // @todo 1: begin: generalize, remove concrete dependencies
1056
1066 public function handleCopiedContent($a_dom, $a_self_ass = true, $a_clone_mobs = false)
1067 {
1068 include_once("./Services/COPage/classes/class.ilCOPagePCDef.php");
1070
1071 // handle question elements
1072 if ($a_self_ass) {
1073 $this->newQuestionCopies($a_dom);
1074 } else {
1075 $this->removeQuestions($a_dom);
1076 }
1077
1078 // handle interactive images
1079 $this->newIIMCopies($a_dom);
1080
1081 // handle media objects
1082 if ($a_clone_mobs) {
1083 $this->newMobCopies($a_dom);
1084 }
1085
1086 // @todo 1: move all functions from above to the new domdoc
1087 if ($a_dom instanceof php4DOMDocument) {
1088 $a_dom = $a_dom->myDOMDocument;
1089 }
1090 foreach ($defs as $def) {
1092 $cl = $def["pc_class"];
1093 if ($cl == 'ilPCPlugged') {
1094 // the page object is provided for ilPageComponentPlugin
1095 ilPCPlugged::handleCopiedPluggedContent($this, $a_dom);
1096 } else {
1097 $cl::handleCopiedContent($a_dom, $a_self_ass, $a_clone_mobs);
1098 }
1099 }
1100 }
1101
1109 public function handleDeleteContent($a_node = null)
1110 {
1111 if (!isset($a_node)) {
1112 $xpc = xpath_new_context($this->dom);
1113 $path = "//PageContent";
1114 $res = xpath_eval($xpc, $path);
1115 $nodes = $res->nodeset;
1116 } else {
1117 $nodes = array($a_node);
1118 }
1119
1120 require_once('Services/COPage/classes/class.ilPCPlugged.php');
1121 foreach ($nodes as $node) {
1122 if ($node instanceof php4DOMNode) {
1123 $node = $node->myDOMNode;
1124 }
1125
1127 if ($node->firstChild->nodeName == 'Plugged') {
1128 ilPCPlugged::handleDeletedPluggedNode($this, $node->firstChild);
1129 }
1130 }
1131 }
1132
1137 public function newIIMCopies($temp_dom)
1138 {
1139 // Get question IDs
1140 $path = "//InteractiveImage/MediaAlias";
1141 $xpc = xpath_new_context($temp_dom);
1142 $res = &xpath_eval($xpc, $path);
1143
1144 $q_ids = array();
1145 include_once("./Services/Link/classes/class.ilInternalLink.php");
1146 for ($i = 0; $i < count($res->nodeset); $i++) {
1147 $or_id = $res->nodeset[$i]->get_attribute("OriginId");
1148
1149 $inst_id = ilInternalLink::_extractInstOfTarget($or_id);
1150 $mob_id = ilInternalLink::_extractObjIdOfTarget($or_id);
1151
1152 if (!($inst_id > 0)) {
1153 if ($mob_id > 0) {
1154 include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
1155 $media_object = new ilObjMediaObject($mob_id);
1156
1157 // now copy this question and change reference to
1158 // new question id
1159 $new_mob = $media_object->duplicate();
1160
1161 $res->nodeset[$i]->set_attribute("OriginId", "il__mob_" . $new_mob->getId());
1162 }
1163 }
1164 }
1165 }
1166
1170 public function newMobCopies($temp_dom)
1171 {
1172 // Get question IDs
1173 $path = "//MediaObject/MediaAlias";
1174 $xpc = xpath_new_context($temp_dom);
1175 $res = &xpath_eval($xpc, $path);
1176
1177 $q_ids = array();
1178 include_once("./Services/Link/classes/class.ilInternalLink.php");
1179 for ($i = 0; $i < count($res->nodeset); $i++) {
1180 $or_id = $res->nodeset[$i]->get_attribute("OriginId");
1181
1182 $inst_id = ilInternalLink::_extractInstOfTarget($or_id);
1183 $mob_id = ilInternalLink::_extractObjIdOfTarget($or_id);
1184
1185 if (!($inst_id > 0)) {
1186 if ($mob_id > 0) {
1187 include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
1188 $media_object = new ilObjMediaObject($mob_id);
1189
1190 // now copy this question and change reference to
1191 // new question id
1192 $new_mob = $media_object->duplicate();
1193
1194 $res->nodeset[$i]->set_attribute("OriginId", "il__mob_" . $new_mob->getId());
1195 }
1196 }
1197 }
1198 }
1199
1204 public function newQuestionCopies(&$temp_dom)
1205 {
1206 // Get question IDs
1207 $path = "//Question";
1208 $xpc = xpath_new_context($temp_dom);
1209 $res = &xpath_eval($xpc, $path);
1210
1211 $q_ids = array();
1212 include_once("./Services/Link/classes/class.ilInternalLink.php");
1213 for ($i = 0; $i < count($res->nodeset); $i++) {
1214 $qref = $res->nodeset[$i]->get_attribute("QRef");
1215
1216 $inst_id = ilInternalLink::_extractInstOfTarget($qref);
1218
1219 if (!($inst_id > 0)) {
1220 if ($q_id > 0) {
1221 include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
1222 $question = assQuestion::_instantiateQuestion($q_id);
1223 // check due to #16557
1224 if (is_object($question) && $question->isComplete()) {
1225 // check if page for question exists
1226 // due to a bug in early 4.2.x version this is possible
1227 if (!ilPageObject::_exists("qpl", $q_id)) {
1228 $question->createPageObject();
1229 }
1230
1231 // now copy this question and change reference to
1232 // new question id
1233 $duplicate_id = $question->duplicate(false);
1234 $res->nodeset[$i]->set_attribute("QRef", "il__qst_" . $duplicate_id);
1235 }
1236 }
1237 }
1238 }
1239 }
1240
1247 public function removeQuestions(&$temp_dom)
1248 {
1249 // Get question IDs
1250 $path = "//Question";
1251 $xpc = xpath_new_context($temp_dom);
1252 $res = &xpath_eval($xpc, $path);
1253 for ($i = 0; $i < count($res->nodeset); $i++) {
1254 $parent_node = $res->nodeset[$i]->parent_node();
1255 $parent_node->unlink_node($parent_node);
1256 }
1257 }
1258
1259 // @todo: end
1260
1267 public function countPageContents()
1268 {
1269 // Get question IDs
1270 $this->buildDom();
1271 $path = "//PageContent";
1272 $xpc = xpath_new_context($this->dom);
1273 $res = &xpath_eval($xpc, $path);
1274 return count($res->nodeset);
1275 }
1276
1281 public function getXMLFromDom(
1282 $a_incl_head = false,
1283 $a_append_mobs = false,
1284 $a_append_bib = false,
1285 $a_append_str = "",
1286 $a_omit_pageobject_tag = false
1287 ) {
1288 if ($a_incl_head) {
1289 //echo "\n<br>#".$this->encoding."#";
1290 return $this->dom->dump_mem(0, $this->encoding);
1291 } else {
1292 // append multimedia object elements
1293 if ($a_append_mobs || $a_append_bib || $a_append_link_info) {
1294 $mobs = "";
1295 $bibs = "";
1296 if ($a_append_mobs) {
1297 $mobs = $this->getMultimediaXML();
1298 }
1299 if ($a_append_bib) {
1300 // deprecated
1301// $bibs = $this->getBibliographyXML();
1302 }
1303 $trans = $this->getLanguageVariablesXML();
1304 //echo htmlentities($this->dom->dump_node($this->node)); exit;
1305 return "<dummy>" . $this->dom->dump_node($this->node) . $mobs . $bibs . $trans . $a_append_str . "</dummy>";
1306 } else {
1307 if (is_object($this->dom)) {
1308 if ($a_omit_pageobject_tag) {
1309 $xml = "";
1310 $childs = $this->node->child_nodes();
1311 for ($i = 0; $i < count($childs); $i++) {
1312 $xml.= $this->dom->dump_node($childs[$i]);
1313 }
1314 return $xml;
1315 } else {
1316 $xml = $this->dom->dump_mem(0, $this->encoding);
1317 $xml = preg_replace('/<\?xml[^>]*>/i', "", $xml);
1318 $xml = preg_replace('/<!DOCTYPE[^>]*>/i', "", $xml);
1319 return $xml;
1320
1321 // don't use dump_node. This gives always entities.
1322 //return $this->dom->dump_node($this->node);
1323 }
1324 } else {
1325 return "";
1326 }
1327 }
1328 }
1329 }
1330
1334 public function getLanguageVariablesXML()
1335 {
1336 $xml = "<LVs>";
1337 $lang_vars = array(
1338 "ed_paste_clip", "ed_edit", "ed_edit_prop", "ed_delete", "ed_moveafter",
1339 "ed_movebefore", "ed_go", "ed_class", "ed_width", "ed_align_left",
1340 "ed_align_right", "ed_align_center", "ed_align_left_float",
1341 "ed_align_right_float", "ed_delete_item", "ed_new_item_before",
1342 "ed_new_item_after", "ed_copy_clip", "please_select", "ed_split_page",
1343 "ed_item_up", "ed_item_down", "ed_split_page_next","ed_enable",
1344 "de_activate", "ed_paste", "ed_edit_multiple", "ed_cut", "ed_copy", "ed_insert_templ",
1345 "ed_click_to_add_pg", "download");
1346
1347 // collect lang vars from pc elements
1348 include_once("./Services/COPage/classes/class.ilCOPagePCDef.php");
1350 foreach ($defs as $def) {
1351 $lang_vars[] = "pc_" . $def["pc_type"];
1352 $lang_vars[] = "ed_insert_" . $def["pc_type"];
1353
1355 $cl = $def["pc_class"];
1356 $lvs = call_user_func($def["pc_class"] . '::getLangVars');
1357 foreach ($lvs as $lv) {
1358 $lang_vars[] = $lv;
1359 }
1360 }
1361
1362 foreach ($lang_vars as $lang_var) {
1363 $this->appendLangVarXML($xml, $lang_var);
1364 }
1365
1366 $xml.= "</LVs>";
1367
1368 return $xml;
1369 }
1370
1371 public function appendLangVarXML(&$xml, $var)
1372 {
1373 $xml.= "<LV name=\"$var\" value=\"" . $this->lng->txt("cont_" . $var) . "\"/>";
1374 }
1375
1376 // @todo begin: move this to paragraph class
1377
1378 public function getFirstParagraphText()
1379 {
1380 if ($this->dom) {
1381 require_once("./Services/COPage/classes/class.ilPCParagraph.php");
1382 $xpc = xpath_new_context($this->dom);
1383 $path = "//Paragraph[1]";
1384 $res = xpath_eval($xpc, $path);
1385 if (count($res->nodeset) > 0) {
1386 $cont_node = $res->nodeset[0]->parent_node();
1387 $par = new ilPCParagraph($this);
1388 $par->setNode($cont_node);
1389 $text = $par->getText();
1390
1391 return $text;
1392 }
1393 }
1394 return "";
1395 }
1396
1403 public function setParagraphContent($a_hier_id, $a_content)
1404 {
1405 $node = $this->getContentNode($a_hier_id);
1406 if (is_object($node)) {
1407 $node->set_content($a_content);
1408 }
1409 }
1410
1411 // @todo end
1412
1413
1422 // @todo: can we do this better
1423 public function setContainsIntLink($a_contains_link)
1424 {
1425 $this->contains_int_link = $a_contains_link;
1426 }
1427
1432 // @todo: can we do this better
1433 public function containsIntLink()
1434 {
1436 }
1437
1443 public function setImportMode($a_val)
1444 {
1445 $this->import_mode = $a_val;
1446 }
1447
1453 public function getImportMode()
1454 {
1455 return $this->import_mode;
1456 }
1457
1458 public function needsImportParsing($a_parse = "")
1459 {
1460 if ($a_parse === true) {
1461 $this->needs_parsing = true;
1462 }
1463 if ($a_parse === false) {
1464 $this->needs_parsing = false;
1465 }
1466 return $this->needs_parsing;
1467 }
1468
1474 // @todo: can we do this better
1475 public function setContainsQuestion($a_val)
1476 {
1477 $this->contains_question = $a_val;
1478 }
1479
1485 public function getContainsQuestion()
1486 {
1487 return $this->contains_question;
1488 }
1489
1490
1495 // @todo: move to media class
1496 public function collectMediaObjects($a_inline_only = true)
1497 {
1498 //echo htmlentities($this->getXMLFromDom());
1499 // determine all media aliases of the page
1500 $xpc = xpath_new_context($this->dom);
1501 $path = "//MediaObject/MediaAlias";
1502 $res = xpath_eval($xpc, $path);
1503 $mob_ids = array();
1504 for ($i = 0; $i < count($res->nodeset); $i++) {
1505 $id_arr = explode("_", $res->nodeset[$i]->get_attribute("OriginId"));
1506 $mob_id = $id_arr[count($id_arr) - 1];
1507 $mob_ids[$mob_id] = $mob_id;
1508 }
1509
1510 // determine all media aliases of interactive images
1511 $xpc = xpath_new_context($this->dom);
1512 $path = "//InteractiveImage/MediaAlias";
1513 $res = xpath_eval($xpc, $path);
1514 for ($i = 0; $i < count($res->nodeset); $i++) {
1515 $id_arr = explode("_", $res->nodeset[$i]->get_attribute("OriginId"));
1516 $mob_id = $id_arr[count($id_arr) - 1];
1517 $mob_ids[$mob_id] = $mob_id;
1518 }
1519
1520 // determine all inline internal media links
1521 $xpc = xpath_new_context($this->dom);
1522 $path = "//IntLink[@Type = 'MediaObject']";
1523 $res = xpath_eval($xpc, $path);
1524
1525 for ($i = 0; $i < count($res->nodeset); $i++) {
1526 if (($res->nodeset[$i]->get_attribute("TargetFrame") == "") ||
1527 (!$a_inline_only)) {
1528 $target = $res->nodeset[$i]->get_attribute("Target");
1529 $id_arr = explode("_", $target);
1530 if (($id_arr[1] == IL_INST_ID) ||
1531 (substr($target, 0, 4) == "il__")) {
1532 $mob_id = $id_arr[count($id_arr) - 1];
1533 if (ilObject::_exists($mob_id)) {
1534 $mob_ids[$mob_id] = $mob_id;
1535 }
1536 }
1537 }
1538 }
1539
1540 return $mob_ids;
1541 }
1542
1543
1547 // @todo: can we do this better?
1548 public function getInternalLinks($a_cnt_multiple = false)
1549 {
1550 // get all internal links of the page
1551 $xpc = xpath_new_context($this->dom);
1552 $path = "//IntLink";
1553 $res = xpath_eval($xpc, $path);
1554
1555 $links = array();
1556 $cnt_multiple = 1;
1557 for ($i = 0; $i < count($res->nodeset); $i++) {
1558 $add = "";
1559 if ($a_cnt_multiple) {
1560 $add = ":" . $cnt_multiple;
1561 }
1562 $target = $res->nodeset[$i]->get_attribute("Target");
1563 $type = $res->nodeset[$i]->get_attribute("Type");
1564 $targetframe = $res->nodeset[$i]->get_attribute("TargetFrame");
1565 $anchor = $res->nodeset[$i]->get_attribute("Anchor");
1566 $links[$target . ":" . $type . ":" . $targetframe . ":" . $anchor . $add] =
1567 array("Target" => $target, "Type" => $type,
1568 "TargetFrame" => $targetframe, "Anchor" => $anchor);
1569
1570 // get links (image map areas) for inline media objects
1571 if ($type == "MediaObject" && $targetframe == "") {
1572 if (substr($target, 0, 4) =="il__") {
1573 $id_arr = explode("_", $target);
1574 $id = $id_arr[count($id_arr) - 1];
1575
1577 foreach ($med_links as $key => $med_link) {
1578 $links[$key] = $med_link;
1579 }
1580 }
1581 }
1582 //echo "<br>-:".$target.":".$type.":".$targetframe.":-";
1583 $cnt_multiple++;
1584 }
1585 unset($xpc);
1586
1587 // get all media aliases
1588 $xpc = xpath_new_context($this->dom);
1589 $path = "//MediaAlias";
1590 $res = xpath_eval($xpc, $path);
1591
1592 require_once("Services/MediaObjects/classes/class.ilMediaItem.php");
1593 for ($i = 0; $i < count($res->nodeset); $i++) {
1594 $oid = $res->nodeset[$i]->get_attribute("OriginId");
1595 if (substr($oid, 0, 4) =="il__") {
1596 $id_arr = explode("_", $oid);
1597 $id = $id_arr[count($id_arr) - 1];
1598
1600 foreach ($med_links as $key => $med_link) {
1601 $links[$key] = $med_link;
1602 }
1603 }
1604 }
1605 unset($xpc);
1606
1607 return $links;
1608 }
1609
1614 // @todo: move to media class
1615 public function getMultimediaXML()
1616 {
1617 $mob_ids = $this->collectMediaObjects();
1618
1619 // get xml of corresponding media objects
1620 $mobs_xml = "";
1621 require_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
1622 foreach ($mob_ids as $mob_id => $dummy) {
1623 if (ilObject::_lookupType($mob_id) == "mob") {
1624 $mob_obj = new ilObjMediaObject($mob_id);
1625 $mobs_xml .= $mob_obj->getXML(IL_MODE_OUTPUT, $a_inst = 0, true);
1626 }
1627 }
1628 //var_dump($mobs_xml);
1629 return $mobs_xml;
1630 }
1631
1635 // @todo: move to media class
1636 public function getMediaAliasElement($a_mob_id, $a_nr = 1)
1637 {
1638 $xpc = xpath_new_context($this->dom);
1639 $path = "//MediaObject/MediaAlias[@OriginId='il__mob_$a_mob_id']";
1640 $res = xpath_eval($xpc, $path);
1641 $mal_node = $res->nodeset[$a_nr - 1];
1642 $mob_node = $mal_node->parent_node();
1643
1644 return $this->dom->dump_node($mob_node);
1645 }
1646
1652 public function validateDom()
1653 {
1654 $this->stripHierIDs();
1655
1656 // possible fix for #14820
1657 libxml_disable_entity_loader(false);
1658
1659 @$this->dom->validate($error);
1660 //var_dump($this->dom); exit;
1661 return $error;
1662 }
1663
1679 // @todo: can we do this better? remove dependencies?
1680 public function addHierIDs()
1681 {
1682 $this->hier_ids = array();
1683 $this->first_row_ids = array();
1684 $this->first_col_ids = array();
1685 $this->list_item_ids = array();
1686 $this->file_item_ids = array();
1687
1688 // set hierarchical ids for Paragraphs, Tables, TableRows and TableData elements
1689 $xpc = xpath_new_context($this->dom);
1690 //$path = "//Paragraph | //Table | //TableRow | //TableData";
1691
1692 $sep = $path = "";
1693 foreach ($this->id_elements as $el) {
1694 $path.= $sep . "//" . $el;
1695 $sep = " | ";
1696 }
1697
1698 $res = xpath_eval($xpc, $path);
1699 for ($i = 0; $i < count($res->nodeset); $i++) {
1700 $cnode = $res->nodeset[$i];
1701 $ctag = $cnode->node_name();
1702
1703 // get hierarchical id of previous sibling
1704 $sib_hier_id = "";
1705 while ($cnode = $cnode->previous_sibling()) {
1706 if (($cnode->node_type() == XML_ELEMENT_NODE)
1707 && $cnode->has_attribute("HierId")) {
1708 $sib_hier_id = $cnode->get_attribute("HierId");
1709 //$sib_hier_id = $id_attr->value();
1710 break;
1711 }
1712 }
1713
1714 if ($sib_hier_id != "") { // set id to sibling id "+ 1"
1715 require_once("./Services/COPage/classes/class.ilPageContent.php");
1716 $node_hier_id = ilPageContent::incEdId($sib_hier_id);
1717 $res->nodeset[$i]->set_attribute("HierId", $node_hier_id);
1718 $this->hier_ids[] = $node_hier_id;
1719 if ($ctag == "TableData") {
1720 if (substr($par_hier_id, strlen($par_hier_id)-2) == "_1") {
1721 $this->first_row_ids[] = $node_hier_id;
1722 }
1723 }
1724 if ($ctag == "ListItem") {
1725 $this->list_item_ids[] = $node_hier_id;
1726 }
1727 if ($ctag == "FileItem") {
1728 $this->file_item_ids[] = $node_hier_id;
1729 }
1730 } else { // no sibling -> node is first child
1731 // get hierarchical id of next parent
1732 $cnode = $res->nodeset[$i];
1733 $par_hier_id = "";
1734 while ($cnode = $cnode->parent_node()) {
1735 if (($cnode->node_type() == XML_ELEMENT_NODE)
1736 && $cnode->has_attribute("HierId")) {
1737 $par_hier_id = $cnode->get_attribute("HierId");
1738 //$par_hier_id = $id_attr->value();
1739 break;
1740 }
1741 }
1742 //echo "<br>par:".$par_hier_id." ($ctag)";
1743 if (($par_hier_id != "") && ($par_hier_id != "pg")) { // set id to parent_id."_1"
1744 $node_hier_id = $par_hier_id . "_1";
1745 $res->nodeset[$i]->set_attribute("HierId", $node_hier_id);
1746 $this->hier_ids[] = $node_hier_id;
1747 if ($ctag == "TableData") {
1748 $this->first_col_ids[] = $node_hier_id;
1749 if (substr($par_hier_id, strlen($par_hier_id)-2) == "_1") {
1750 $this->first_row_ids[] = $node_hier_id;
1751 }
1752 }
1753 if ($ctag == "ListItem") {
1754 $this->list_item_ids[] = $node_hier_id;
1755 }
1756 if ($ctag == "FileItem") {
1757 $this->file_item_ids[] = $node_hier_id;
1758 }
1759 } else { // no sibling, no parent -> first node
1760 $node_hier_id = "1";
1761 $res->nodeset[$i]->set_attribute("HierId", $node_hier_id);
1762 $this->hier_ids[] = $node_hier_id;
1763 }
1764 }
1765 }
1766
1767 // set special hierarchical id "pg" for pageobject
1768 $xpc = xpath_new_context($this->dom);
1769 $path = "//PageObject";
1770 $res = xpath_eval($xpc, $path);
1771 for ($i = 0; $i < count($res->nodeset); $i++) { // should only be 1
1772 $res->nodeset[$i]->set_attribute("HierId", "pg");
1773 $this->hier_ids[] = "pg";
1774 }
1775 unset($xpc);
1776 }
1777
1781 public function getHierIds()
1782 {
1783 return $this->hier_ids;
1784 }
1785
1789 // @todo: move to table classes
1790 public function getFirstRowIds()
1791 {
1792 return $this->first_row_ids;
1793 }
1794
1798 // @todo: move to table classes
1799 public function getFirstColumnIds()
1800 {
1801 return $this->first_col_ids;
1802 }
1803
1807 // @todo: move to list class
1808 public function getListItemIds()
1809 {
1810 return $this->list_item_ids;
1811 }
1812
1816 // @todo: move to file item class
1817 public function getFileItemIds()
1818 {
1819 return $this->file_item_ids;
1820 }
1821
1825 public function stripHierIDs()
1826 {
1827 if (is_object($this->dom)) {
1828 $xpc = xpath_new_context($this->dom);
1829 $path = "//*[@HierId]";
1830 $res = xpath_eval($xpc, $path);
1831 for ($i = 0; $i < count($res->nodeset); $i++) { // should only be 1
1832 if ($res->nodeset[$i]->has_attribute("HierId")) {
1833 $res->nodeset[$i]->remove_attribute("HierId");
1834 }
1835 }
1836 unset($xpc);
1837 }
1838 }
1839
1843 public function getHierIdsForPCIds($a_pc_ids)
1844 {
1845 if (!is_array($a_pc_ids) || count($a_pc_ids) == 0) {
1846 return array();
1847 }
1848 $ret = array();
1849
1850 if (is_object($this->dom)) {
1851 $xpc = xpath_new_context($this->dom);
1852 $path = "//*[@PCID]";
1853 $res = xpath_eval($xpc, $path);
1854 for ($i = 0; $i < count($res->nodeset); $i++) { // should only be 1
1855 $pc_id = $res->nodeset[$i]->get_attribute("PCID");
1856 if (in_array($pc_id, $a_pc_ids)) {
1857 $ret[$pc_id] = $res->nodeset[$i]->get_attribute("HierId");
1858 }
1859 }
1860 unset($xpc);
1861 }
1862 //var_dump($ret);
1863 return $ret;
1864 }
1865
1869 // @todo: move to file item class
1870 public function addFileSizes()
1871 {
1872 $xpc = xpath_new_context($this->dom);
1873 $path = "//FileItem";
1874 $res = xpath_eval($xpc, $path);
1875 for ($i = 0; $i < count($res->nodeset); $i++) {
1876 $cnode = $res->nodeset[$i];
1877 $size_node = $this->dom->create_element("Size");
1878 $size_node = $cnode->append_child($size_node);
1879
1880 $childs = $cnode->child_nodes();
1881 $size = "";
1882 for ($j = 0; $j < count($childs); $j++) {
1883 if ($childs[$j]->node_name() == "Identifier") {
1884 if ($childs[$j]->has_attribute("Entry")) {
1885 $entry = $childs[$j]->get_attribute("Entry");
1886 $entry_arr = explode("_", $entry);
1887 $id = $entry_arr[count($entry_arr) - 1];
1888 require_once("./Modules/File/classes/class.ilObjFile.php");
1890 }
1891 }
1892 }
1893 $size_node->set_content($size);
1894 }
1895
1896 unset($xpc);
1897 }
1898
1903 // @todo: possible to improve this?
1904 public function resolveIntLinks($a_link_map = null)
1905 {
1906 $changed = false;
1907
1908 $this->log->debug("start");
1909
1910 // resolve normal internal links
1911 $xpc = xpath_new_context($this->dom);
1912 $path = "//IntLink";
1913 $res = xpath_eval($xpc, $path);
1914 for ($i = 0; $i < count($res->nodeset); $i++) {
1915 $target = $res->nodeset[$i]->get_attribute("Target");
1916 $type = $res->nodeset[$i]->get_attribute("Type");
1917
1918 if ($a_link_map == null) {
1920 $this->log->debug("no map, type: " . $type . ", target: " . $target . ", new target: " . $new_target);
1921 // echo "-".$new_target."-".$type."-".$target."-"; exit;
1922 } else {
1923 $nt = explode("_", $a_link_map[$target]);
1924 $new_target = false;
1925 if ($nt[1] == IL_INST_ID) {
1926 $new_target = "il__" . $nt[2] . "_" . $nt[3];
1927 }
1928 $this->log->debug("map, type: " . $type . ", target: " . $target . ", new target: " . $new_target);
1929 }
1930 if ($new_target !== false) {
1931 $res->nodeset[$i]->set_attribute("Target", $new_target);
1932 $changed = true;
1933 } else { // check wether link target is same installation
1934 if (ilInternalLink::_extractInstOfTarget($target) == IL_INST_ID &&
1935 IL_INST_ID > 0 && $type != "RepositoryItem") {
1937 if (ilInternalLink::_exists($type, $new_target)) {
1938 $res->nodeset[$i]->set_attribute("Target", $new_target);
1939 $changed = true;
1940 }
1941 }
1942 }
1943 }
1944 unset($xpc);
1945
1946 // resolve internal links in map areas
1947 $xpc = xpath_new_context($this->dom);
1948 $path = "//MediaAlias";
1949 $res = xpath_eval($xpc, $path);
1950 //echo "<br><b>page::resolve</b><br>";
1951 //echo "Content:".htmlentities($this->getXMLFromDOM()).":<br>";
1952 for ($i = 0; $i < count($res->nodeset); $i++) {
1953 $orig_id = $res->nodeset[$i]->get_attribute("OriginId");
1954 $id_arr = explode("_", $orig_id);
1955 $mob_id = $id_arr[count($id_arr) - 1];
1957 }
1958 return $changed;
1959 }
1960
1967 // @todo: move to media classes?
1968 public function resolveMediaAliases($a_mapping, $a_reuse_existing_by_import = false)
1969 {
1970 // resolve normal internal links
1971 $xpc = xpath_new_context($this->dom);
1972 $path = "//MediaAlias";
1973 $res = xpath_eval($xpc, $path);
1974 $changed = false;
1975 for ($i = 0; $i < count($res->nodeset); $i++) {
1976 // get the ID of the import file from the xml
1977 $old_id = $res->nodeset[$i]->get_attribute("OriginId");
1978 $old_id = explode("_", $old_id);
1979 $old_id = $old_id[count($old_id) - 1];
1980 $new_id = "";
1981 $import_id = "";
1982 // get the new id from the current mapping
1983 if ($a_mapping[$old_id] > 0) {
1984 $new_id = $a_mapping[$old_id];
1985 if ($a_reuse_existing_by_import) {
1986 // this should work, if the lm has been imported in a translation installation and re-exported
1987 $import_id = ilObject::_lookupImportId($new_id);
1988 $imp = explode("_", $import_id);
1989 if ($imp[1] == IL_INST_ID && $imp[2] == "mob" && ilObject::_lookupType($imp[3]) == "mob") {
1990 $new_id = $imp[3];
1991 }
1992 }
1993 }
1994 // now check, if the translation has been done just by changing text in the exported
1995 // translation file
1996 if ($import_id == "" && $a_reuse_existing_by_import) {
1997 // if the old_id is also referred by the page content of the default language
1998 // we assume that this media object is unchanged
1999 include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
2000 $med_of_def_lang = ilObjMediaObject::_getMobsOfObject($this->getParentType() . ":pg", $this->getId(), 0, "-");
2001 if (in_array($old_id, $med_of_def_lang)) {
2002 $new_id = $old_id;
2003 }
2004 }
2005 if ($new_id != "") {
2006 $res->nodeset[$i]->set_attribute("OriginId", "il__mob_" . $new_id);
2007 $changed = true;
2008 }
2009 }
2010 unset($xpc);
2011 return $changed;
2012 }
2013
2020 // @todo: move to iim classes?
2021 public function resolveIIMMediaAliases($a_mapping)
2022 {
2023 // resolve normal internal links
2024 $xpc = xpath_new_context($this->dom);
2025 $path = "//InteractiveImage/MediaAlias";
2026 $res = xpath_eval($xpc, $path);
2027 $changed = false;
2028 for ($i = 0; $i < count($res->nodeset); $i++) {
2029 $old_id = $res->nodeset[$i]->get_attribute("OriginId");
2030 if ($a_mapping[$old_id] > 0) {
2031 $res->nodeset[$i]->set_attribute("OriginId", "il__mob_" . $a_mapping[$old_id]);
2032 $changed = true;
2033 }
2034 }
2035 unset($xpc);
2036
2037 return $changed;
2038 }
2039
2046 // @todo: move to file classes?
2047 public function resolveFileItems($a_mapping)
2048 {
2049 // resolve normal internal links
2050 $xpc = xpath_new_context($this->dom);
2051 $path = "//FileItem/Identifier";
2052 $res = xpath_eval($xpc, $path);
2053 $changed = false;
2054 for ($i = 0; $i < count($res->nodeset); $i++) {
2055 $old_id = $res->nodeset[$i]->get_attribute("Entry");
2056 $old_id = explode("_", $old_id);
2057 $old_id = $old_id[count($old_id) - 1];
2058 if ($a_mapping[$old_id] > 0) {
2059 $res->nodeset[$i]->set_attribute("Entry", "il__file_" . $a_mapping[$old_id]);
2060 $changed = true;
2061 }
2062 }
2063 unset($xpc);
2064
2065 return $changed;
2066 }
2067
2072 // @todo: move to question classes
2073 public function resolveQuestionReferences($a_mapping)
2074 {
2075 // resolve normal internal links
2076 $xpc = xpath_new_context($this->dom);
2077 $path = "//Question";
2078 $res = xpath_eval($xpc, $path);
2079 $updated = false;
2080 for ($i = 0; $i < count($res->nodeset); $i++) {
2081 $qref = $res->nodeset[$i]->get_attribute("QRef");
2082
2083 if (isset($a_mapping[$qref])) {
2084 $res->nodeset[$i]->set_attribute("QRef", "il__qst_" . $a_mapping[$qref]["pool"]);
2085 $updated = true;
2086 }
2087 }
2088 unset($xpc);
2089
2090 return $updated;
2091 }
2092
2093
2100 // @todo: generalize, internal links usage info
2101 public function moveIntLinks($a_from_to)
2102 {
2103 $this->buildDom();
2104
2105 $changed = false;
2106
2107 // resolve normal internal links
2108 $xpc = xpath_new_context($this->dom);
2109 $path = "//IntLink";
2110 $res = xpath_eval($xpc, $path);
2111 for ($i = 0; $i < count($res->nodeset); $i++) {
2112 $target = $res->nodeset[$i]->get_attribute("Target");
2113 $type = $res->nodeset[$i]->get_attribute("Type");
2115 if ($a_from_to[$obj_id] > 0 && is_int(strpos($target, "__"))) {
2116 if ($type == "PageObject" && ilLMObject::_lookupType($a_from_to[$obj_id]) == "pg") {
2117 $res->nodeset[$i]->set_attribute("Target", "il__pg_" . $a_from_to[$obj_id]);
2118 $changed = true;
2119 }
2120 if ($type == "StructureObject" && ilLMObject::_lookupType($a_from_to[$obj_id]) == "st") {
2121 $res->nodeset[$i]->set_attribute("Target", "il__st_" . $a_from_to[$obj_id]);
2122 $changed = true;
2123 }
2124 if ($type == "PortfolioPage") {
2125 $res->nodeset[$i]->set_attribute("Target", "il__ppage_" . $a_from_to[$obj_id]);
2126 $changed = true;
2127 }
2128 }
2129 }
2130 unset($xpc);
2131
2132 // map areas
2133 $this->addHierIDs();
2134 $xpc = xpath_new_context($this->dom);
2135 $path = "//MediaAlias";
2136 $res = xpath_eval($xpc, $path);
2137
2138 require_once("Services/MediaObjects/classes/class.ilMediaItem.php");
2139 require_once("Services/COPage/classes/class.ilMediaAliasItem.php");
2140
2141 for ($i = 0; $i < count($res->nodeset); $i++) {
2142 $media_object_node = $res->nodeset[$i]->parent_node();
2143 $page_content_node = $media_object_node->parent_node();
2144 $c_hier_id = $page_content_node->get_attribute("HierId");
2145
2146 // first check, wheter we got instance map areas -> take these
2147 $std_alias_item = new ilMediaAliasItem(
2148 $this->dom,
2149 $c_hier_id,
2150 "Standard"
2151 );
2152 $areas = $std_alias_item->getMapAreas();
2153 $correction_needed = false;
2154 if (count($areas) > 0) {
2155 // check if correction needed
2156 foreach ($areas as $area) {
2157 if ($area["Type"] == "PageObject" ||
2158 $area["Type"] == "StructureObject") {
2159 $t = $area["Target"];
2160 $tid = _extractObjIdOfTarget($t);
2161 if ($a_from_to[$tid] > 0) {
2162 $correction_needed = true;
2163 }
2164 }
2165 }
2166 } else {
2167 $areas = array();
2168
2169 // get object map areas and check whether at least one must
2170 // be corrected
2171 $oid = $res->nodeset[$i]->get_attribute("OriginId");
2172 if (substr($oid, 0, 4) =="il__") {
2173 $id_arr = explode("_", $oid);
2174 $id = $id_arr[count($id_arr) - 1];
2175
2176 $mob = new ilObjMediaObject($id);
2177 $med_item = $mob->getMediaItem("Standard");
2178 $med_areas = $med_item->getMapAreas();
2179
2180 foreach ($med_areas as $area) {
2181 $link_type = ($area->getLinkType() == "int")
2182 ? "IntLink"
2183 : "ExtLink";
2184
2185 $areas[] = array(
2186 "Nr" => $area->getNr(),
2187 "Shape" => $area->getShape(),
2188 "Coords" => $area->getCoords(),
2189 "Link" => array(
2190 "LinkType" => $link_type,
2191 "Href" => $area->getHref(),
2192 "Title" => $area->getTitle(),
2193 "Target" => $area->getTarget(),
2194 "Type" => $area->getType(),
2195 "TargetFrame" => $area->getTargetFrame()
2196 )
2197 );
2198
2199 if ($area->getType() == "PageObject" ||
2200 $area->getType() == "StructureObject") {
2201 $t = $area->getTarget();
2203 if ($a_from_to[$tid] > 0) {
2204 $correction_needed = true;
2205 }
2206 //var_dump($a_from_to);
2207 }
2208 }
2209 }
2210 }
2211
2212 // correct map area links
2213 if ($correction_needed) {
2214 $changed = true;
2215 $std_alias_item->deleteAllMapAreas();
2216 foreach ($areas as $area) {
2217 if ($area["Link"]["LinkType"] == "IntLink") {
2218 $target = $area["Link"]["Target"];
2219 $type = $area["Link"]["Type"];
2221 if ($a_from_to[$obj_id] > 0) {
2222 if ($type == "PageObject" && ilLMObject::_lookupType($a_from_to[$obj_id]) == "pg") {
2223 $area["Link"]["Target"] = "il__pg_" . $a_from_to[$obj_id];
2224 }
2225 if ($type == "StructureObject" && ilLMObject::_lookupType($a_from_to[$obj_id]) == "st") {
2226 $area["Link"]["Target"] = "il__st_" . $a_from_to[$obj_id];
2227 }
2228 }
2229 }
2230
2231 $std_alias_item->addMapArea(
2232 $area["Shape"],
2233 $area["Coords"],
2234 $area["Link"]["Title"],
2235 array( "Type" => $area["Link"]["Type"],
2236 "TargetFrame" => $area["Link"]["TargetFrame"],
2237 "Target" => $area["Link"]["Target"],
2238 "Href" => $area["Link"]["Href"],
2239 "LinkType" => $area["Link"]["LinkType"],
2240 )
2241 );
2242 }
2243 }
2244 }
2245 unset($xpc);
2246
2247 return $changed;
2248 }
2249
2255 // @todo: generalize, internal links usage info
2256 public static function _handleImportRepositoryLinks($a_rep_import_id, $a_rep_type, $a_rep_ref_id)
2257 {
2258 include_once("./Services/Link/classes/class.ilInternalLink.php");
2259
2260 //echo "-".$a_rep_import_id."-".$a_rep_ref_id."-";
2262 "obj",
2263 ilInternalLink::_extractObjIdOfTarget($a_rep_import_id),
2264 ilInternalLink::_extractInstOfTarget($a_rep_import_id)
2265 );
2266 //var_dump($sources);
2267 foreach ($sources as $source) {
2268 //echo "A";
2269 if ($source["type"] == "lm:pg") {
2270 //echo "B";
2271 include_once("./Modules/LearningModule/classes/class.ilLMPage.php");
2272 if (self::_exists("lm", $source["id"], $source["lang"])) {
2273 $page_obj = new ilLMPage($source["id"], 0, $source["lang"]);
2274 if (!$page_obj->page_not_found) {
2275 //echo "C";
2276 $page_obj->handleImportRepositoryLink(
2277 $a_rep_import_id,
2278 $a_rep_type,
2279 $a_rep_ref_id
2280 );
2281 }
2282 $page_obj->update();
2283 }
2284 }
2285 }
2286 }
2287
2288 // @todo: generalize, internal links usage info
2289 public function handleImportRepositoryLink($a_rep_import_id, $a_rep_type, $a_rep_ref_id)
2290 {
2291 $this->buildDom();
2292
2293 // resolve normal internal links
2294 $xpc = xpath_new_context($this->dom);
2295 $path = "//IntLink";
2296 $res = xpath_eval($xpc, $path);
2297 //echo "1";
2298 for ($i = 0; $i < count($res->nodeset); $i++) {
2299 //echo "2";
2300 $target = $res->nodeset[$i]->get_attribute("Target");
2301 $type = $res->nodeset[$i]->get_attribute("Type");
2302 if ($target == $a_rep_import_id && $type == "RepositoryItem") {
2303 //echo "setting:"."il__".$a_rep_type."_".$a_rep_ref_id;
2304 $res->nodeset[$i]->set_attribute(
2305 "Target",
2306 "il__" . $a_rep_type . "_" . $a_rep_ref_id
2307 );
2308 }
2309 }
2310 unset($xpc);
2311 }
2312
2318 public function handleRepositoryLinksOnCopy($a_mapping, $a_source_ref_id)
2319 {
2321 $objDefinition = $this->obj_definition;
2322
2323 $this->buildDom();
2324 $this->log->debug("Handle repository links...");
2325
2326 // resolve normal internal links
2327 $xpc = xpath_new_context($this->dom);
2328 $path = "//IntLink";
2329 $res = xpath_eval($xpc, $path);
2330 for ($i = 0; $i < count($res->nodeset); $i++) {
2331 $target = $res->nodeset[$i]->get_attribute("Target");
2332 $type = $res->nodeset[$i]->get_attribute("Type");
2333 $this->log->debug("Target: " . $target);
2334 $t = explode("_", $target);
2335 if ($type == "RepositoryItem" && ((int) $t[1] == 0 || (int) $t[1] == IL_INST_ID)) {
2336 if (isset($a_mapping[$t[3]])) {
2337 // we have a mapping -> replace the ID
2338 $this->log->debug("... replace " . $t[3] . " with " . $a_mapping[$t[3]] . ".");
2339 $res->nodeset[$i]->set_attribute(
2340 "Target",
2341 "il__obj_" . $a_mapping[$t[3]]
2342 );
2343 } elseif ($this->tree->isGrandChild($a_source_ref_id, $t[3])) {
2344 // we have no mapping, but the linked object is child of the original node -> remove link
2345 $this->log->debug("... remove links.");
2346 if ($res->nodeset[$i]->parent_node()->node_name() == "MapArea") { // simply remove map areas
2347 $parent = $res->nodeset[$i]->parent_node();
2348 $parent->unlink_node($parent);
2349 } else { // replace link by content of the link for other internal links
2350 $source_node = $res->nodeset[$i];
2351 $new_node = $source_node->clone_node(true);
2352 $new_node->unlink_node($new_node);
2353 $childs = $new_node->child_nodes();
2354 for ($j = 0; $j < count($childs); $j++) {
2355 $this->log->debug("... move node $j " . $childs[$j]->node_name() . " before " . $source_node->node_name());
2356 $source_node->insert_before($childs[$j], $source_node);
2357 }
2358 $source_node->unlink_node($source_node);
2359 }
2360 }
2361 }
2362 }
2363 unset($xpc);
2364
2365 // resolve normal external links
2366 $ilias_url = parse_url(ILIAS_HTTP_PATH);
2367 $xpc = xpath_new_context($this->dom);
2368 $path = "//ExtLink";
2369 $res = xpath_eval($xpc, $path);
2370 for ($i = 0; $i < count($res->nodeset); $i++) {
2371 $href = $res->nodeset[$i]->get_attribute("Href");
2372 $this->log->debug("Href: " . $href);
2373
2374 $url = parse_url($href);
2375
2376 // only handle links on same host
2377 $this->log->debug("Host: " . $url["host"]);
2378 if ($url["host"] != "" && $url["host"] != $ilias_url["host"]) {
2379 continue;
2380 }
2381
2382 // get parameters
2383 $par = array();
2384 foreach (explode("&", $url["query"]) as $p) {
2385 $p = explode("=", $p);
2386 $par[$p[0]] = $p[1];
2387 }
2388
2389 $target_client_id = $par["client_id"];
2390 if ($target_client_id != "" && $target_client_id != CLIENT_ID) {
2391 continue;
2392 }
2393
2394 // get ref id
2395 $ref_id = 0;
2396 if (is_int(strpos($href, "goto.php"))) {
2397 $t = explode("_", $par["target"]);
2398 if ($objDefinition->isRBACObject($t[0])) {
2399 $ref_id = (int) $t[1];
2400 $type = $t[0];
2401 }
2402 } elseif (is_int(strpos($href, "ilias.php"))) {
2403 $ref_id = (int) $par["ref_id"];
2404 }
2405
2406
2407 if ($ref_id > 0) {
2408 if (isset($a_mapping[$ref_id])) {
2409 $new_ref_id = $a_mapping[$ref_id];
2410 $new_href = "";
2411 // we have a mapping -> replace the ID
2412 if (is_int(strpos($href, "goto.php"))) {
2413 $nt = str_replace($type . "_" . $ref_id, $type . "_" . $new_ref_id, $par["target"]);
2414 $new_href = str_replace("target=" . $par["target"], "target=" . $nt, $href);
2415 } elseif (is_int(strpos($href, "ilias.php"))) {
2416 $new_href = str_replace("ref_id=" . $par["ref_id"], "ref_id=" . $new_ref_id, $href);
2417 }
2418 if ($new_href != "") {
2419 $this->log->debug("... ext link replace " . $href . " with " . $new_href . ".");
2420 $res->nodeset[$i]->set_attribute("Href", $new_href);
2421 }
2422 } elseif ($tree->isGrandChild($a_source_ref_id, $ref_id)) {
2423 // we have no mapping, but the linked object is child of the original node -> remove link
2424 $this->log->debug("... remove ext links.");
2425 if ($res->nodeset[$i]->parent_node()->node_name() == "MapArea") { // simply remove map areas
2426 $parent = $res->nodeset[$i]->parent_node();
2427 $parent->unlink_node($parent);
2428 } else { // replace link by content of the link for other internal links
2429 $source_node = $res->nodeset[$i];
2430 $new_node = $source_node->clone_node(true);
2431 $new_node->unlink_node($new_node);
2432 $childs = $new_node->child_nodes();
2433 for ($j = 0; $j < count($childs); $j++) {
2434 $this->log->debug("... move node $j " . $childs[$j]->node_name() . " before " . $source_node->node_name());
2435 $source_node->insert_before($childs[$j], $source_node);
2436 }
2437 $source_node->unlink_node($source_node);
2438 }
2439 }
2440 }
2441 }
2442 unset($xpc);
2443 }
2444
2445
2449 public function createFromXML()
2450 {
2451 $empty = false;
2452 if ($this->getXMLContent() == "") {
2453 $this->setXMLContent("<PageObject></PageObject>");
2454 $empty = true;
2455 }
2456
2457 $content = $this->getXMLContent();
2458 $this->buildDom(true);
2459 $dom_doc = $this->getDomDoc();
2460
2461 $iel = $this->containsDeactivatedElements($content);
2462 $inl = $this->containsIntLinks($content);
2463
2464 // create object
2465 $this->db->insert("page_object", array(
2466 "page_id" => array("integer", $this->getId()),
2467 "parent_id" => array("integer", $this->getParentId()),
2468 "lang" => array("text", $this->getLanguage()),
2469 "content" => array("clob", $content),
2470 "parent_type" => array("text", $this->getParentType()),
2471 "create_user" => array("integer", $this->user->getId()),
2472 "last_change_user" => array("integer", $this->user->getId()),
2473 "active" => array("integer", (int) $this->getActive()),
2474 "activation_start" => array("timestamp", $this->getActivationStart()),
2475 "activation_end" => array("timestamp", $this->getActivationEnd()),
2476 "show_activation_info" => array("integer", (int) $this->getShowActivationInfo()),
2477 "inactive_elements" => array("integer", $iel),
2478 "int_links" => array("integer", $inl),
2479 "created" => array("timestamp", ilUtil::now()),
2480 "last_change" => array("timestamp", ilUtil::now())
2481 ));
2482
2483 // after update event
2484 $this->__afterUpdate($dom_doc, $content, true, $empty);
2485 }
2486
2487
2496 public function updateFromXML()
2497 {
2498 $this->log->debug("ilPageObject, updateFromXML(): start, id: " . $this->getId());
2499
2500 $content = $this->getXMLContent();
2501
2502 $this->log->debug("ilPageObject, updateFromXML(): content: " . substr($content, 0, 100));
2503
2504 $this->buildDom(true);
2505 $dom_doc = $this->getDomDoc();
2506
2507 $iel = $this->containsDeactivatedElements($content);
2508 $inl = $this->containsIntLinks($content);
2509
2510 $this->db->update("page_object", array(
2511 "content" => array("clob", $content),
2512 "parent_id" => array("integer", $this->getParentId()),
2513 "last_change_user" => array("integer", $this->user->getId()),
2514 "last_change" => array("timestamp", ilUtil::now()),
2515 "active" => array("integer", $this->getActive()),
2516 "activation_start" => array("timestamp", $this->getActivationStart()),
2517 "activation_end" => array("timestamp", $this->getActivationEnd()),
2518 "inactive_elements" => array("integer", $iel),
2519 "int_links" => array("integer", $inl),
2520 ), array(
2521 "page_id" => array("integer", $this->getId()),
2522 "parent_type" => array("text", $this->getParentType()),
2523 "lang" => array("text", $this->getLanguage())
2524 ));
2525
2526 // after update event
2527 $this->__afterUpdate($dom_doc, $content);
2528
2529 $this->log->debug("ilPageObject, updateFromXML(): end");
2530
2531 return true;
2532 }
2533
2540 final protected function __afterUpdate($a_domdoc, $a_xml, $a_creation = false, $a_empty = false)
2541 {
2542 // we do not need this if we are creating an empty page
2543 if (!$a_creation || !$a_empty) {
2544 // save internal link information
2545 // the page object is responsible to do this, since it "offers" the
2546 // internal link feature pc and page classes
2547 $this->saveInternalLinks($a_domdoc);
2548
2549 // save style usage
2550 $this->saveStyleUsage($a_domdoc);
2551
2552 // pc classes hook
2553 include_once("./Services/COPage/classes/class.ilCOPagePCDef.php");
2555 foreach ($defs as $def) {
2557 $cl = $def["pc_class"];
2558 call_user_func($def["pc_class"] . '::afterPageUpdate', $this, $a_domdoc, $a_xml, $a_creation);
2559 }
2560 }
2561
2562 // call page hook
2563 $this->afterUpdate($a_domdoc, $a_xml);
2564
2565 // call update listeners
2566 $this->callUpdateListeners();
2567 }
2568
2575 public function afterUpdate()
2576 {
2577 }
2578
2579
2584 public function update($a_validate = true, $a_no_history = false)
2585 {
2586 $this->log->debug("ilPageObject, update(): start, id: " . $this->getId());
2587
2588 $lm_set = new ilSetting("lm");
2589
2590 // add missing pc ids
2591 if (!$this->checkPCIds()) {
2592 $this->insertPCIds();
2593 }
2594
2595 // test validating
2596 if ($a_validate) {
2597 $errors = $this->validateDom();
2598 }
2599 //var_dump($errors); exit;
2600 if (empty($errors) && !$this->getEditLock()) {
2601 include_once("./Services/User/classes/class.ilUserUtil.php");
2602 $lock = $this->getEditLockInfo();
2603 $errors[0] = array(0 => 0,
2604 1 => "nocontent#" . $this->lng->txt("cont_not_saved_edit_lock_expired") . "<br />" .
2605 $this->lng->txt("obj_usr") . ": " .
2606 ilUserUtil::getNamePresentation($lock["edit_lock_user"]) . "<br />" .
2607 $this->lng->txt("content_until") . ": " .
2608 ilDatePresentation::formatDate(new ilDateTime($lock["edit_lock_until"], IL_CAL_UNIX))
2609 );
2610 }
2611
2612 if (!empty($errors)) {
2613 $this->log->debug("ilPageObject, update(): errors: " . print_r($errors, true));
2614 }
2615
2616 //echo "-".htmlentities($this->getXMLFromDom())."-"; exit;
2617 if (empty($errors)) {
2618 // @todo 1: is this page type or pc content type
2619 // related -> plugins should be able to hook in!?
2621
2622 // get xml content
2623 $content = $this->getXMLFromDom();
2624 $dom_doc = $this->getDomDoc();
2625
2626 // this needs to be locked
2627
2628 // write history entry
2629 $old_set = $this->db->query("SELECT * FROM page_object WHERE " .
2630 "page_id = " . $this->db->quote($this->getId(), "integer") . " AND " .
2631 "parent_type = " . $this->db->quote($this->getParentType(), "text") . " AND " .
2632 "lang = " . $this->db->quote($this->getLanguage(), "text"));
2633 $last_nr_set = $this->db->query("SELECT max(nr) as mnr FROM page_history WHERE " .
2634 "page_id = " . $this->db->quote($this->getId(), "integer") . " AND " .
2635 "parent_type = " . $this->db->quote($this->getParentType(), "text") . " AND " .
2636 "lang = " . $this->db->quote($this->getLanguage(), "text"));
2637 $last_nr = $this->db->fetchAssoc($last_nr_set);
2638 if ($old_rec = $this->db->fetchAssoc($old_set)) {
2639 // only save, if something has changed
2640 // added user id to the check for ilias 5.0, 7.10.2014
2641 if (($content != $old_rec["content"] || $this->user->getId() != $old_rec["last_change_user"]) &&
2642 !$a_no_history && !$this->history_saved && $lm_set->get("page_history", 1)) {
2643 if ($old_rec["content"] != "<PageObject></PageObject>") {
2644 $this->db->manipulateF(
2645 "DELETE FROM page_history WHERE " .
2646 "page_id = %s AND parent_type = %s AND hdate = %s AND lang = %s",
2647 array("integer", "text", "timestamp", "text"),
2648 array($old_rec["page_id"], $old_rec["parent_type"], $old_rec["last_change"], $old_rec["lang"])
2649 );
2650
2651 // the following lines are a workaround for
2652 // bug 6741
2653 $last_c = $old_rec["last_change"];
2654 if ($last_c == "") {
2655 $last_c = ilUtil::now();
2656 }
2657
2658 $this->db->insert("page_history", array(
2659 "page_id" => array("integer", $old_rec["page_id"]),
2660 "parent_type" => array("text", $old_rec["parent_type"]),
2661 "lang" => array("text", $old_rec["lang"]),
2662 "hdate" => array("timestamp", $last_c),
2663 "parent_id" => array("integer", $old_rec["parent_id"]),
2664 "content" => array("clob", $old_rec["content"]),
2665 "user_id" => array("integer", $old_rec["last_change_user"]),
2666 "ilias_version" => array("text", ILIAS_VERSION_NUMERIC),
2667 "nr" => array("integer", (int) $last_nr["mnr"] + 1)
2668 ));
2669
2670 $old_content = $old_rec["content"];
2671 $old_domdoc = new DOMDocument();
2672 $old_nr = $last_nr["mnr"] + 1;
2673 $old_domdoc->loadXML('<?xml version="1.0" encoding="UTF-8"?>' . $old_content);
2674
2675 // after history entry creation event
2676 $this->__afterHistoryEntry($old_domdoc, $old_content, $old_nr);
2677
2678 $this->history_saved = true; // only save one time
2679 } else {
2680 $this->history_saved = true; // do not save on first change
2681 }
2682 }
2683 }
2684 //echo htmlentities($content);
2685 $em = (trim($content) == "<PageObject/>")
2686 ? 1
2687 : 0;
2688
2689 // @todo: pass dom instead?
2690 $iel = $this->containsDeactivatedElements($content);
2691 $inl = $this->containsIntLinks($content);
2692
2693 $this->db->update("page_object", array(
2694 "content" => array("clob", $content),
2695 "parent_id" => array("integer", $this->getParentId()),
2696 "last_change_user" => array("integer", $this->user->getId()),
2697 "last_change" => array("timestamp", ilUtil::now()),
2698 "is_empty" => array("integer", $em),
2699 "active" => array("integer", $this->getActive()),
2700 "activation_start" => array("timestamp", $this->getActivationStart()),
2701 "activation_end" => array("timestamp", $this->getActivationEnd()),
2702 "show_activation_info" => array("integer", $this->getShowActivationInfo()),
2703 "inactive_elements" => array("integer", $iel),
2704 "int_links" => array("integer", $inl),
2705 ), array(
2706 "page_id" => array("integer", $this->getId()),
2707 "parent_type" => array("text", $this->getParentType()),
2708 "lang" => array("text", $this->getLanguage())
2709 ));
2710
2711 // after update event
2712 $this->__afterUpdate($dom_doc, $content);
2713
2714 $this->log->debug("ilPageObject, update(): updated and returning true, content: " . substr($this->getXMLContent(), 0, 100));
2715
2716 //echo "<br>PageObject::update:".htmlentities($this->getXMLContent()).":";
2717 return true;
2718 } else {
2719 return $errors;
2720 }
2721 }
2722
2723
2724
2728 public function delete()
2729 {
2730 $copg_logger = ilLoggerFactory::getLogger('copg');
2731 $copg_logger->debug(
2732 "ilPageObject: Delete called for ID '" . $this->getId() . "'," .
2733 " parent type: '" . $this->getParentType() . "', " .
2734 " hist nr: '" . $this->old_nr . "', " .
2735 " lang: '" . $this->getLanguage() . "', "
2736 );
2737
2738 $mobs = array();
2739 $files = array();
2740
2741 if (!$this->page_not_found) {
2742 $this->buildDom();
2743 $mobs = $this->collectMediaObjects(false);
2744 }
2745 include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
2746 $mobs2 = ilObjMediaObject::_getMobsOfObject($this->getParentType() . ":pg", $this->getId(), false);
2747 foreach ($mobs2 as $m) {
2748 if (!in_array($m, $mobs)) {
2749 $mobs[] = $m;
2750 }
2751 }
2752
2753 $copg_logger->debug("ilPageObject: ... found " . count($mobs) . " media objects.");
2754
2755 $this->__beforeDelete();
2756
2757 // treat plugged content
2758 $this->handleDeleteContent();
2759
2760 // delete style usages
2761 $this->deleteStyleUsages(false);
2762
2763 // delete internal links
2764 $this->deleteInternalLinks();
2765
2766 // delete all mob usages
2767 ilObjMediaObject::_deleteAllUsages($this->getParentType() . ":pg", $this->getId());
2768
2769 // delete news
2770 include_once("./Services/News/classes/class.ilNewsItem.php");
2772 $this->getParentId(),
2773 $this->getParentType(),
2774 $this->getId(),
2775 "pg"
2776 );
2777
2778 // delete page_object entry
2779 $this->db->manipulate("DELETE FROM page_object " .
2780 "WHERE page_id = " . $this->db->quote($this->getId(), "integer") .
2781 " AND parent_type= " . $this->db->quote($this->getParentType(), "text"));
2782
2783 // delete media objects
2784 foreach ($mobs as $mob_id) {
2785 $copg_logger->debug("ilPageObject: ... processing mob " . $mob_id . ".");
2786
2787 if (ilObject::_lookupType($mob_id) != 'mob') {
2788 $copg_logger->debug("ilPageObject: ... type mismatch. Ignoring mob " . $mob_id . ".");
2789 continue;
2790 }
2791
2792 if (ilObject::_exists($mob_id)) {
2793 $copg_logger->debug("ilPageObject: ... delete mob " . $mob_id . ".");
2794
2795 $mob_obj = new ilObjMediaObject($mob_id);
2796 $mob_obj->delete();
2797 } else {
2798 $copg_logger->debug("ilPageObject: ... missing mob " . $mob_id . ".");
2799 }
2800 }
2801 }
2802
2808 final protected function __beforeDelete()
2809 {
2810 // pc classes hook
2811 include_once("./Services/COPage/classes/class.ilCOPagePCDef.php");
2813 foreach ($defs as $def) {
2815 $cl = $def["pc_class"];
2816 call_user_func($def["pc_class"] . '::beforePageDelete', $this);
2817 }
2818 }
2819
2825 final protected function __afterHistoryEntry($a_old_domdoc, $a_old_content, $a_old_nr)
2826 {
2827 // save style usage
2828 $this->saveStyleUsage($a_old_domdoc, $a_old_nr);
2829
2830 // pc classes hook
2831 include_once("./Services/COPage/classes/class.ilCOPagePCDef.php");
2833 foreach ($defs as $def) {
2835 $cl = $def["pc_class"];
2836 call_user_func($def["pc_class"] . '::afterPageHistoryEntry', $this, $a_old_domdoc, $a_old_content, $a_old_nr);
2837 }
2838 }
2839
2845 public function saveStyleUsage($a_domdoc, $a_old_nr = 0)
2846 {
2847 // media aliases
2848 $xpath = new DOMXPath($a_domdoc);
2849 $path = "//Paragraph | //Section | //MediaAlias | //FileItem" .
2850 " | //Table | //TableData | //Tabs | //List";
2851 $nodes = $xpath->query($path);
2852 $usages = array();
2853 foreach ($nodes as $node) {
2854 switch ($node->localName) {
2855 case "Paragraph":
2856 $sname = $node->getAttribute("Characteristic");
2857 $stype = "text_block";
2858 $template = 0;
2859 break;
2860
2861 case "Section":
2862 $sname = $node->getAttribute("Characteristic");
2863 $stype = "section";
2864 $template = 0;
2865 break;
2866
2867 case "MediaAlias":
2868 $sname = $node->getAttribute("Class");
2869 $stype = "media_cont";
2870 $template = 0;
2871 break;
2872
2873 case "FileItem":
2874 $sname = $node->getAttribute("Class");
2875 $stype = "flist_li";
2876 $template = 0;
2877 break;
2878
2879 case "Table":
2880 $sname = $node->getAttribute("Template");
2881 if ($sname == "") {
2882 $sname = $node->getAttribute("Class");
2883 $stype = "table";
2884 $template = 0;
2885 } else {
2886 $stype = "table";
2887 $template = 1;
2888 }
2889 break;
2890
2891 case "TableData":
2892 $sname = $node->getAttribute("Class");
2893 $stype = "table_cell";
2894 $template = 0;
2895 break;
2896
2897 case "Tabs":
2898 $sname = $node->getAttribute("Template");
2899 if ($sname != "") {
2900 if ($node->getAttribute("Type") == "HorizontalAccordion") {
2901 $stype = "haccordion";
2902 }
2903 if ($node->getAttribute("Type") == "VerticalAccordion") {
2904 $stype = "vaccordion";
2905 }
2906 }
2907 $template = 1;
2908 break;
2909
2910 case "List":
2911 $sname = $node->getAttribute("Class");
2912 if ($node->getAttribute("Type") == "Ordered") {
2913 $stype = "list_o";
2914 } else {
2915 $stype = "list_u";
2916 }
2917 $template = 0;
2918 break;
2919 }
2920 if ($sname != "" && $stype != "") {
2921 $usages[$sname . ":" . $stype . ":" . $template] = array("sname" => $sname,
2922 "stype" => $stype, "template" => $template);
2923 }
2924 }
2925
2926
2927 $this->deleteStyleUsages($a_old_nr);
2928
2929 foreach ($usages as $u) {
2930 $id = $this->db->nextId('page_style_usage');
2931
2932 $this->db->manipulate("INSERT INTO page_style_usage " .
2933 "(id, page_id, page_type, page_lang, page_nr, template, stype, sname) VALUES (" .
2934 $this->db->quote($id, "integer") . "," .
2935 $this->db->quote($this->getId(), "integer") . "," .
2936 $this->db->quote($this->getParentType(), "text") . "," .
2937 $this->db->quote($this->getLanguage(), "text") . "," .
2938 $this->db->quote($a_old_nr, "integer") . "," .
2939 $this->db->quote($u["template"], "integer") . "," .
2940 $this->db->quote($u["stype"], "text") . "," .
2941 $this->db->quote($u["sname"], "text") .
2942 ")");
2943 }
2944 }
2945
2952 public function deleteStyleUsages($a_old_nr = 0)
2953 {
2954 if ($a_old_nr !== false) {
2955 $and_old_nr = " AND page_nr = " . $this->db->quote($a_old_nr, "integer");
2956 }
2957
2958 $this->db->manipulate(
2959 "DELETE FROM page_style_usage WHERE " .
2960 " page_id = " . $this->db->quote($this->getId(), "integer") .
2961 " AND page_type = " . $this->db->quote($this->getParentType(), "text") .
2962 " AND page_lang = " . $this->db->quote($this->getLanguage(), "text") .
2963 $and_old_nr
2964 );
2965 }
2966
2967
2972 // @todo: move to content include class
2974 {
2975 include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
2976 include_once("./Modules/File/classes/class.ilObjFile.php");
2978 $this->getParentType() . ":pg",
2979 $this->getId()
2980 );
2982 $this->getParentType() . ":pg",
2983 $this->getId()
2984 );
2985 $objs = array_merge($mobs, $files);
2987 }
2988
2995 public function deleteInternalLinks()
2996 {
2997 include_once("./Services/Link/classes/class.ilInternalLink.php");
2999 $this->getParentType() . ":pg",
3000 $this->getId(),
3001 $this->getLanguage()
3002 );
3003 }
3004
3005
3011 // @todo: move to specific classes, internal link use info
3012 public function saveInternalLinks($a_domdoc)
3013 {
3014 $this->deleteInternalLinks();
3015
3016 // query IntLink elements
3017 $xpath = new DOMXPath($a_domdoc);
3018 $nodes = $xpath->query('//IntLink');
3019 foreach ($nodes as $node) {
3020 $link_type = $node->getAttribute("Type");
3021
3022 switch ($link_type) {
3023 case "StructureObject":
3024 $t_type = "st";
3025 break;
3026
3027 case "PageObject":
3028 $t_type = "pg";
3029 break;
3030
3031 case "GlossaryItem":
3032 $t_type = "git";
3033 break;
3034
3035 case "MediaObject":
3036 $t_type = "mob";
3037 break;
3038
3039 case "RepositoryItem":
3040 $t_type = "obj";
3041 break;
3042
3043 case "File":
3044 $t_type = "file";
3045 break;
3046
3047 case "WikiPage":
3048 $t_type = "wpage";
3049 break;
3050
3051 case "PortfolioPage":
3052 $t_type = "ppage";
3053 break;
3054
3055 case "User":
3056 $t_type = "user";
3057 break;
3058 }
3059
3060 $target = $node->getAttribute("Target");
3061 $target_arr = explode("_", $target);
3062 $t_id = $target_arr[count($target_arr) - 1];
3063
3064 // link to other internal object
3065 if (is_int(strpos($target, "__"))) {
3066 $t_inst = 0;
3067 } else { // link to unresolved object in other installation
3068 $t_inst = $target_arr[1];
3069 }
3070
3071 if ($t_id > 0) {
3073 $this->getParentType() . ":pg",
3074 $this->getId(),
3075 $t_type,
3076 $t_id,
3077 $t_inst,
3078 $this->getLanguage()
3079 );
3080 }
3081 }
3082 }
3083
3087 public function create()
3088 {
3089 $this->createFromXML();
3090 }
3091
3099 public function deleteContent($a_hid, $a_update = true, $a_pcid = "")
3100 {
3101 $curr_node = $this->getContentNode($a_hid, $a_pcid);
3102 $this->handleDeleteContent($curr_node);
3103 $curr_node->unlink_node($curr_node);
3104 if ($a_update) {
3105 return $this->update();
3106 }
3107 }
3108
3109
3117 public function deleteContents($a_hids, $a_update = true, $a_self_ass = false)
3118 {
3119 if (!is_array($a_hids)) {
3120 return;
3121 }
3122 foreach ($a_hids as $a_hid) {
3123 $a_hid = explode(":", $a_hid);
3124 //echo "-".$a_hid[0]."-".$a_hid[1]."-";
3125
3126 // @todo 1: hook
3127 // do not delete question nodes in assessment pages
3128 if (!$this->checkForTag("Question", $a_hid[0], $a_hid[1]) || $a_self_ass) {
3129 $curr_node = $this->getContentNode($a_hid[0], $a_hid[1]);
3130 if (is_object($curr_node)) {
3131 $parent_node = $curr_node->parent_node();
3132 if ($parent_node->node_name() != "TableRow") {
3133 $this->handleDeleteContent($curr_node);
3134 $curr_node->unlink_node($curr_node);
3135 }
3136 }
3137 }
3138 }
3139 if ($a_update) {
3140 return $this->update();
3141 }
3142 }
3143
3149 public function cutContents($a_hids)
3150 {
3151 $this->copyContents($a_hids);
3152 return $this->deleteContents($a_hids, true, $this->getPageConfig()->getEnableSelfAssessment());
3153 }
3154
3160 public function copyContents($a_hids)
3161 {
3163
3164 if (!is_array($a_hids)) {
3165 return;
3166 }
3167
3168 $time = date("Y-m-d H:i:s", time());
3169
3170 $hier_ids = array();
3171 $skip = array();
3172 foreach ($a_hids as $a_hid) {
3173 if ($a_hid == "") {
3174 continue;
3175 }
3176 $a_hid = explode(":", $a_hid);
3177
3178 // check, whether new hid is child of existing one or vice versa
3179 reset($hier_ids);
3180 foreach ($hier_ids as $h) {
3181 if ($h . "_" == substr($a_hid[0], 0, strlen($h) + 1)) {
3182 $skip[] = $a_hid[0];
3183 }
3184 if ($a_hid[0] . "_" == substr($h, 0, strlen($a_hid[0]) + 1)) {
3185 $skip[] = $h;
3186 }
3187 }
3188 $pc_id[$a_hid[0]] = $a_hid[1];
3189 if ($a_hid[0] != "") {
3190 $hier_ids[$a_hid[0]] = $a_hid[0];
3191 }
3192 }
3193 foreach ($skip as $s) {
3194 unset($hier_ids[$s]);
3195 }
3196 include_once("./Services/COPage/classes/class.ilPageContent.php");
3197 $hier_ids = ilPageContent::sortHierIds($hier_ids);
3198 $nr = 1;
3199 foreach ($hier_ids as $hid) {
3200 $curr_node = $this->getContentNode($hid, $pc_id[$hid]);
3201 if (is_object($curr_node)) {
3202 if ($curr_node->node_name() == "PageContent") {
3203 $content = $this->dom->dump_node($curr_node);
3204 // remove pc and hier ids
3205 $content = preg_replace('/PCID=\"[a-z0-9]*\"/i', "", $content);
3206 $content = preg_replace('/HierId=\"[a-z0-9_]*\"/i', "", $content);
3207
3208 $user->addToPCClipboard($content, $time, $nr);
3209 $nr++;
3210 }
3211 }
3212 }
3213 include_once("./Modules/LearningModule/classes/class.ilEditClipboard.php");
3215 }
3216
3220 public function pasteContents($a_hier_id, $a_self_ass = false)
3221 {
3223
3224 $a_hid = explode(":", $a_hier_id);
3225 $content = $user->getPCClipboardContent();
3226
3227 // we insert from last to first, because we insert all at the
3228 // same hier_id
3229 for ($i = count($content) - 1; $i >= 0; $i--) {
3230 $c = $content[$i];
3231 $temp_dom = domxml_open_mem(
3232 '<?xml version="1.0" encoding="UTF-8"?>' . $c,
3234 $error
3235 );
3236 if (empty($error)) {
3237 $this->handleCopiedContent($temp_dom, $a_self_ass);
3238 $xpc = xpath_new_context($temp_dom);
3239 $path = "//PageContent";
3240 $res = xpath_eval($xpc, $path);
3241 if (count($res->nodeset) > 0) {
3242 $new_pc_node = $res->nodeset[0];
3243 $cloned_pc_node = $new_pc_node->clone_node(true);
3244 $cloned_pc_node->unlink_node($cloned_pc_node);
3245 $this->insertContentNode(
3246 $cloned_pc_node,
3247 $a_hid[0],
3249 $a_hid[1]
3250 );
3251 }
3252 } else {
3253 //var_dump($error);
3254 }
3255 }
3256 $e = $this->update();
3257 //var_dump($e);
3258 }
3259
3263 public function switchEnableMultiple($a_hids, $a_update = true, $a_self_ass = false)
3264 {
3265 if (!is_array($a_hids)) {
3266 return;
3267 }
3268 $obj = &$this->content_obj;
3269
3270 foreach ($a_hids as $a_hid) {
3271 $a_hid = explode(":", $a_hid);
3272 $curr_node = $this->getContentNode($a_hid[0], $a_hid[1]);
3273 if (is_object($curr_node)) {
3274 if ($curr_node->node_name() == "PageContent") {
3275 $cont_obj = $this->getContentObject($a_hid[0], $a_hid[1]);
3276 if ($cont_obj->isEnabled()) {
3277 // do not deactivate question nodes in assessment pages
3278 if (!$this->checkForTag("Question", $a_hid[0], $a_hid[1]) || $a_self_ass) {
3279 $cont_obj->disable();
3280 }
3281 } else {
3282 $cont_obj->enable();
3283 }
3284 }
3285 }
3286 }
3287
3288 if ($a_update) {
3289 return $this->update();
3290 }
3291 }
3292
3293
3301 public function deleteContentFromHierId($a_hid, $a_update = true)
3302 {
3303 $hier_ids = $this->getHierIds();
3304
3305 // iterate all hierarchical ids
3306 foreach ($hier_ids as $hier_id) {
3307 // delete top level nodes only
3308 if (!is_int(strpos($hier_id, "_"))) {
3309 if ($hier_id != "pg" && $hier_id >= $a_hid) {
3310 $curr_node = $this->getContentNode($hier_id);
3311 $this->handleDeleteContent($curr_node);
3312 $curr_node->unlink_node($curr_node);
3313 }
3314 }
3315 }
3316 if ($a_update) {
3317 return $this->update();
3318 }
3319 }
3320
3328 public function deleteContentBeforeHierId($a_hid, $a_update = true)
3329 {
3330 $hier_ids = $this->getHierIds();
3331
3332 // iterate all hierarchical ids
3333 foreach ($hier_ids as $hier_id) {
3334 // delete top level nodes only
3335 if (!is_int(strpos($hier_id, "_"))) {
3336 if ($hier_id != "pg" && $hier_id < $a_hid) {
3337 $curr_node = $this->getContentNode($hier_id);
3338 $this->handleDeleteContent($curr_node);
3339 $curr_node->unlink_node($curr_node);
3340 }
3341 }
3342 }
3343 if ($a_update) {
3344 return $this->update();
3345 }
3346 }
3347
3348
3356 public static function _moveContentAfterHierId(&$a_source_page, &$a_target_page, $a_hid)
3357 {
3358 $hier_ids = $a_source_page->getHierIds();
3359
3360 $copy_ids = array();
3361
3362 // iterate all hierarchical ids
3363 foreach ($hier_ids as $hier_id) {
3364 // move top level nodes only
3365 if (!is_int(strpos($hier_id, "_"))) {
3366 if ($hier_id != "pg" && $hier_id >= $a_hid) {
3367 $copy_ids[] = $hier_id;
3368 }
3369 }
3370 }
3371 asort($copy_ids);
3372
3373 $parent_node = $a_target_page->getContentNode("pg");
3374 $target_dom = $a_target_page->getDom();
3375 $parent_childs = $parent_node->child_nodes();
3376 $cnt_parent_childs = count($parent_childs);
3377 //echo "-$cnt_parent_childs-";
3378 $first_child = $parent_childs[0];
3379 foreach ($copy_ids as $copy_id) {
3380 $source_node = $a_source_page->getContentNode($copy_id);
3381
3382 $new_node = $source_node->clone_node(true);
3383 $new_node->unlink_node($new_node);
3384
3385 $source_node->unlink_node($source_node);
3386
3387 if ($cnt_parent_childs == 0) {
3388 $new_node = $parent_node->append_child($new_node);
3389 } else {
3390 //$target_dom->import_node($new_node);
3391 $new_node = $first_child->insert_before($new_node, $first_child);
3392 }
3393 $parent_childs = $parent_node->child_nodes();
3394
3395 //$cnt_parent_childs++;
3396 }
3397
3398 $a_target_page->update();
3399 $a_source_page->update();
3400 }
3401
3405 public function insertContent(&$a_cont_obj, $a_pos, $a_mode = IL_INSERT_AFTER, $a_pcid = "")
3406 {
3407 //echo "-".$a_pos."-".$a_pcid."-";
3408 // move mode into container elements is always INSERT_CHILD
3409 $curr_node = $this->getContentNode($a_pos, $a_pcid);
3410 $curr_name = $curr_node->node_name();
3411
3412 // @todo: try to generalize this
3413 if (($curr_name == "TableData") || ($curr_name == "PageObject") ||
3414 ($curr_name == "ListItem") || ($curr_name == "Section")
3415 || ($curr_name == "Tab") || ($curr_name == "ContentPopup")
3416 || ($curr_name == "GridCell")) {
3417 $a_mode = IL_INSERT_CHILD;
3418 }
3419
3420 $hid = $curr_node->get_attribute("HierId");
3421 if ($hid != "") {
3422 //echo "-".$a_pos."-".$hid."-";
3423 $a_pos = $hid;
3424 }
3425
3426 if ($a_mode != IL_INSERT_CHILD) { // determine parent hierarchical id
3427 // of sibling at $a_pos
3428 $pos = explode("_", $a_pos);
3429 $target_pos = array_pop($pos);
3430 $parent_pos = implode($pos, "_");
3431 } else { // if we should insert a child, $a_pos is alreade the hierarchical id
3432 // of the parent node
3433 $parent_pos = $a_pos;
3434 }
3435
3436 // get the parent node
3437 if ($parent_pos != "") {
3438 $parent_node = $this->getContentNode($parent_pos);
3439 } else {
3440 $parent_node = $this->getNode();
3441 }
3442
3443 // count the parent children
3444 $parent_childs = $parent_node->child_nodes();
3445 $cnt_parent_childs = count($parent_childs);
3446 //echo "ZZ$a_mode";
3447 switch ($a_mode) {
3448 // insert new node after sibling at $a_pos
3449 case IL_INSERT_AFTER:
3450 $new_node = $a_cont_obj->getNode();
3451 //$a_pos = ilPageContent::incEdId($a_pos);
3452 //$curr_node = $this->getContentNode($a_pos);
3453//echo "behind $a_pos:";
3454 if ($succ_node = $curr_node->next_sibling()) {
3455 $new_node = $succ_node->insert_before($new_node, $succ_node);
3456 } else {
3457 //echo "movin doin append_child";
3458 $new_node = $parent_node->append_child($new_node);
3459 }
3460 $a_cont_obj->setNode($new_node);
3461 break;
3462
3463 case IL_INSERT_BEFORE:
3464//echo "INSERT_BEF";
3465 $new_node = $a_cont_obj->getNode();
3466 $succ_node = $this->getContentNode($a_pos);
3467 $new_node = $succ_node->insert_before($new_node, $succ_node);
3468 $a_cont_obj->setNode($new_node);
3469 break;
3470
3471 // insert new node as first child of parent $a_pos (= $a_parent)
3472 case IL_INSERT_CHILD:
3473//echo "insert as child:parent_childs:$cnt_parent_childs:<br>";
3474 $new_node = $a_cont_obj->getNode();
3475 if ($cnt_parent_childs == 0) {
3476 $new_node = $parent_node->append_child($new_node);
3477 } else {
3478 $new_node = $parent_childs[0]->insert_before($new_node, $parent_childs[0]);
3479 }
3480 $a_cont_obj->setNode($new_node);
3481//echo "PP";
3482 break;
3483 }
3484
3485 //check for PlaceHolder to remove in EditMode-keep in Layout Mode
3486 if (!$this->getPageConfig()->getEnablePCType("PlaceHolder")) {
3487 $sub_nodes = $curr_node->child_nodes() ;
3488 foreach ($sub_nodes as $sub_node) {
3489 if ($sub_node->node_name() == "PlaceHolder") {
3490 $curr_node->unlink_node();
3491 }
3492 }
3493 }
3494 }
3495
3499 public function insertContentNode(&$a_cont_node, $a_pos, $a_mode = IL_INSERT_AFTER, $a_pcid = "")
3500 {
3501 // move mode into container elements is always INSERT_CHILD
3502 $curr_node = $this->getContentNode($a_pos, $a_pcid);
3503 $curr_name = $curr_node->node_name();
3504
3505 // @todo: try to generalize
3506 if (($curr_name == "TableData") || ($curr_name == "PageObject") ||
3507 ($curr_name == "ListItem") || ($curr_name == "Section")
3508 || ($curr_name == "Tab") || ($curr_name == "ContentPopup")
3509 || ($curr_name == "GridCell")) {
3510 $a_mode = IL_INSERT_CHILD;
3511 }
3512
3513 $hid = $curr_node->get_attribute("HierId");
3514 if ($hid != "") {
3515 $a_pos = $hid;
3516 }
3517
3518 if ($a_mode != IL_INSERT_CHILD) { // determine parent hierarchical id
3519 // of sibling at $a_pos
3520 $pos = explode("_", $a_pos);
3521 $target_pos = array_pop($pos);
3522 $parent_pos = implode($pos, "_");
3523 } else { // if we should insert a child, $a_pos is alreade the hierarchical id
3524 // of the parent node
3525 $parent_pos = $a_pos;
3526 }
3527
3528 // get the parent node
3529 if ($parent_pos != "") {
3530 $parent_node = $this->getContentNode($parent_pos);
3531 } else {
3532 $parent_node = $this->getNode();
3533 }
3534
3535 // count the parent children
3536 $parent_childs = $parent_node->child_nodes();
3537 $cnt_parent_childs = count($parent_childs);
3538
3539 switch ($a_mode) {
3540 // insert new node after sibling at $a_pos
3541 case IL_INSERT_AFTER:
3542 //$new_node = $a_cont_obj->getNode();
3543 if ($succ_node = $curr_node->next_sibling()) {
3544 $a_cont_node = $succ_node->insert_before($a_cont_node, $succ_node);
3545 } else {
3546 $a_cont_node = $parent_node->append_child($a_cont_node);
3547 }
3548 //$a_cont_obj->setNode($new_node);
3549 break;
3550
3551 case IL_INSERT_BEFORE:
3552 //$new_node = $a_cont_obj->getNode();
3553 $succ_node = $this->getContentNode($a_pos);
3554 $a_cont_node = $succ_node->insert_before($a_cont_node, $succ_node);
3555 //$a_cont_obj->setNode($new_node);
3556 break;
3557
3558 // insert new node as first child of parent $a_pos (= $a_parent)
3559 case IL_INSERT_CHILD:
3560 //$new_node = $a_cont_obj->getNode();
3561 if ($cnt_parent_childs == 0) {
3562 $a_cont_node = $parent_node->append_child($a_cont_node);
3563 } else {
3564 $a_cont_node = $parent_childs[0]->insert_before($a_cont_node, $parent_childs[0]);
3565 }
3566 //$a_cont_obj->setNode($new_node);
3567 break;
3568 }
3569 }
3570
3575 public function moveContentBefore($a_source, $a_target, $a_spcid = "", $a_tpcid = "")
3576 {
3577 if ($a_source == $a_target) {
3578 return;
3579 }
3580
3581 // clone the node
3582 $content = $this->getContentObject($a_source, $a_spcid);
3583 $source_node = $content->getNode();
3584 $clone_node = $source_node->clone_node(true);
3585
3586 // delete source node
3587 $this->deleteContent($a_source, false, $a_spcid);
3588
3589 // insert cloned node at target
3590 $content->setNode($clone_node);
3591 $this->insertContent($content, $a_target, IL_INSERT_BEFORE, $a_tpcid);
3592 return $this->update();
3593 }
3594
3599 public function moveContentAfter($a_source, $a_target, $a_spcid = "", $a_tpcid = "")
3600 {
3601 if ($a_source == $a_target) {
3602 return;
3603 }
3604
3605 // clone the node
3606 $content = $this->getContentObject($a_source, $a_spcid);
3607 $source_node = $content->getNode();
3608 $clone_node = $source_node->clone_node(true);
3609
3610 // delete source node
3611 $this->deleteContent($a_source, false, $a_spcid);
3612
3613 // insert cloned node at target
3614 $content->setNode($clone_node);
3615 $this->insertContent($content, $a_target, IL_INSERT_AFTER, $a_tpcid);
3616 return $this->update();
3617 }
3618
3622 // @todo: move to paragraph
3623 public function bbCode2XML(&$a_content)
3624 {
3625 $a_content = preg_replace('/\[com\]/i', "<Comment>", $a_content);
3626 $a_content = preg_replace('/\[\/com\]/i', "</Comment>", $a_content);
3627 $a_content = preg_replace('/\[emp]/i', "<Emph>", $a_content);
3628 $a_content = preg_replace('/\[\/emp\]/i', "</Emph>", $a_content);
3629 $a_content = preg_replace('/\[str]/i', "<Strong>", $a_content);
3630 $a_content = preg_replace('/\[\/str\]/i', "</Strong>", $a_content);
3631 }
3632
3637 public function insertInstIntoIDs($a_inst, $a_res_ref_to_obj_id = true)
3638 {
3639 // insert inst id into internal links
3640 $xpc = xpath_new_context($this->dom);
3641 $path = "//IntLink";
3642 $res = xpath_eval($xpc, $path);
3643 for ($i = 0; $i < count($res->nodeset); $i++) {
3644 $target = $res->nodeset[$i]->get_attribute("Target");
3645 $type = $res->nodeset[$i]->get_attribute("Type");
3646
3647 if (substr($target, 0, 4) == "il__") {
3648 $id = substr($target, 4, strlen($target) - 4);
3649
3650 // convert repository links obj_<ref_id> to <type>_<obj_id>
3651 // this leads to bug 6685.
3652 if ($a_res_ref_to_obj_id && $type == "RepositoryItem") {
3653 $id_arr = explode("_", $id);
3654
3655 // changed due to bug 6685
3656 $ref_id = $id_arr[1];
3657 $obj_id = ilObject::_lookupObjId($id_arr[1]);
3658
3659 $otype = ilObject::_lookupType($obj_id);
3660 if ($obj_id > 0) {
3661 // changed due to bug 6685
3662 // the ref_id should be used, if the content is
3663 // imported on the same installation
3664 // the obj_id should be used, if a different
3665 // installation imports, but has an import_id for
3666 // the object id.
3667 $id = $otype . "_" . $obj_id . "_" . $ref_id;
3668 //$id = $otype."_".$ref_id;
3669 }
3670 }
3671 $new_target = "il_" . $a_inst . "_" . $id;
3672 $res->nodeset[$i]->set_attribute("Target", $new_target);
3673 }
3674 }
3675 unset($xpc);
3676
3677 // @todo: move to media/fileitems/questions, ...
3678
3679 // insert inst id into media aliases
3680 $xpc = xpath_new_context($this->dom);
3681 $path = "//MediaAlias";
3682 $res = xpath_eval($xpc, $path);
3683 for ($i = 0; $i < count($res->nodeset); $i++) {
3684 $origin_id = $res->nodeset[$i]->get_attribute("OriginId");
3685 if (substr($origin_id, 0, 4) == "il__") {
3686 $new_id = "il_" . $a_inst . "_" . substr($origin_id, 4, strlen($origin_id) - 4);
3687 $res->nodeset[$i]->set_attribute("OriginId", $new_id);
3688 }
3689 }
3690 unset($xpc);
3691
3692 // insert inst id file item identifier entries
3693 $xpc = xpath_new_context($this->dom);
3694 $path = "//FileItem/Identifier";
3695 $res = xpath_eval($xpc, $path);
3696 for ($i = 0; $i < count($res->nodeset); $i++) {
3697 $origin_id = $res->nodeset[$i]->get_attribute("Entry");
3698 if (substr($origin_id, 0, 4) == "il__") {
3699 $new_id = "il_" . $a_inst . "_" . substr($origin_id, 4, strlen($origin_id) - 4);
3700 $res->nodeset[$i]->set_attribute("Entry", $new_id);
3701 }
3702 }
3703 unset($xpc);
3704
3705 // insert inst id into question references
3706 $xpc = xpath_new_context($this->dom);
3707 $path = "//Question";
3708 $res = xpath_eval($xpc, $path);
3709 for ($i = 0; $i < count($res->nodeset); $i++) {
3710 $qref = $res->nodeset[$i]->get_attribute("QRef");
3711 //echo "<br>setted:".$qref;
3712 if (substr($qref, 0, 4) == "il__") {
3713 $new_id = "il_" . $a_inst . "_" . substr($qref, 4, strlen($qref) - 4);
3714 //echo "<br>setting:".$new_id;
3715 $res->nodeset[$i]->set_attribute("QRef", $new_id);
3716 }
3717 }
3718 unset($xpc);
3719
3720 // insert inst id into content snippets
3721 $xpc = xpath_new_context($this->dom);
3722 $path = "//ContentInclude";
3723 $res = xpath_eval($xpc, $path);
3724 for ($i = 0; $i < count($res->nodeset); $i++) {
3725 $ci = $res->nodeset[$i]->get_attribute("InstId");
3726 if ($ci == "") {
3727 $res->nodeset[$i]->set_attribute("InstId", $a_inst);
3728 }
3729 }
3730 unset($xpc);
3731 }
3732
3736 public function checkPCIds()
3737 {
3738 $this->builddom();
3739 $mydom = $this->dom;
3740
3741 $sep = $path = "";
3742 foreach ($this->id_elements as $el) {
3743 $path.= $sep . "//" . $el . "[not(@PCID)]";
3744 $sep = " | ";
3745 $path.= $sep . "//" . $el . "[@PCID='']";
3746 }
3747
3748 $xpc = xpath_new_context($mydom);
3749 $res = &xpath_eval($xpc, $path);
3750
3751 if (count($res->nodeset) > 0) {
3752 return false;
3753 }
3754 return true;
3755 }
3756
3763 public function getAllPCIds()
3764 {
3765 $this->builddom();
3766 $mydom = $this->dom;
3767
3768 $pcids = array();
3769
3770 $sep = $path = "";
3771 foreach ($this->id_elements as $el) {
3772 $path.= $sep . "//" . $el . "[@PCID]";
3773 $sep = " | ";
3774 }
3775
3776 // get existing ids
3777 $xpc = xpath_new_context($mydom);
3778 $res = &xpath_eval($xpc, $path);
3779
3780 for ($i = 0; $i < count($res->nodeset); $i++) {
3781 $node = $res->nodeset[$i];
3782 $pcids[] = $node->get_attribute("PCID");
3783 }
3784 return $pcids;
3785 }
3786
3793 public function existsPCId($a_pc_id)
3794 {
3795 $this->builddom();
3796 $mydom = $this->dom;
3797
3798 $pcids = array();
3799
3800 $sep = $path = "";
3801 foreach ($this->id_elements as $el) {
3802 $path.= $sep . "//" . $el . "[@PCID='" . $a_pc_id . "']";
3803 $sep = " | ";
3804 }
3805
3806 // get existing ids
3807 $xpc = xpath_new_context($mydom);
3808 $res = &xpath_eval($xpc, $path);
3809 return (count($res->nodeset) > 0);
3810 }
3811
3818 public function generatePcId($a_pc_ids = false)
3819 {
3820 if ($a_pc_ids === false) {
3821 $a_pc_ids = $this->getAllPCIds();
3822 }
3823 $id = ilUtil::randomHash(10, $a_pc_ids);
3824 return $id;
3825 }
3826
3827
3831 public function insertPCIds()
3832 {
3833 $this->builddom();
3834 $mydom = $this->dom;
3835
3836 $pcids = $this->getAllPCIds();
3837
3838 // add missing ones
3839 $sep = $path = "";
3840 foreach ($this->id_elements as $el) {
3841 $path.= $sep . "//" . $el . "[not(@PCID)]";
3842 $sep = " | ";
3843 $path.= $sep . "//" . $el . "[@PCID='']";
3844 $sep = " | ";
3845 }
3846 $xpc = xpath_new_context($mydom);
3847 $res = &xpath_eval($xpc, $path);
3848
3849 for ($i = 0; $i < count($res->nodeset); $i++) {
3850 $node = $res->nodeset[$i];
3851 $id = ilUtil::randomHash(10, $pcids);
3852 $pcids[] = $id;
3853 //echo "setting-".$id."-";
3854 $res->nodeset[$i]->set_attribute("PCID", $id);
3855 }
3856 }
3857
3861 public function getPageContentsHashes()
3862 {
3863 $this->builddom();
3864 $this->addHierIds();
3865 $mydom = $this->dom;
3866
3867 // get existing ids
3868 $path = "//PageContent";
3869 $xpc = xpath_new_context($mydom);
3870 $res = &xpath_eval($xpc, $path);
3871
3872 $hashes = array();
3873 require_once("./Services/COPage/classes/class.ilPCParagraph.php");
3874 for ($i = 0; $i < count($res->nodeset); $i++) {
3875 $hier_id = $res->nodeset[$i]->get_attribute("HierId");
3876 $pc_id = $res->nodeset[$i]->get_attribute("PCID");
3877 $dump = $mydom->dump_node($res->nodeset[$i]);
3878 if (($hpos = strpos($dump, ' HierId="' . $hier_id . '"')) > 0) {
3879 $dump = substr($dump, 0, $hpos) .
3880 substr($dump, $hpos + strlen(' HierId="' . $hier_id . '"'));
3881 }
3882
3883 $childs = $res->nodeset[$i]->child_nodes();
3884 $content = "";
3885 if ($childs[0] && $childs[0]->node_name() == "Paragraph") {
3886 $content = $mydom->dump_node($childs[0]);
3887 $content = substr(
3888 $content,
3889 strpos($content, ">") + 1,
3890 strrpos($content, "<") - (strpos($content, ">") + 1)
3891 );
3892 //var_dump($content);
3893 $content = ilPCParagraph::xml2output($content);
3894 //var_dump($content);
3895 }
3896 //$hashes[$hier_id] =
3897 // array("PCID" => $pc_id, "hash" => md5($dump));
3898 $hashes[$pc_id] =
3899 array("hier_id" => $hier_id, "hash" => md5($dump), "content" => $content);
3900 }
3901
3902 return $hashes;
3903 }
3904
3908 // @todo: move to questions
3909 public function getQuestionIds()
3910 {
3911 $this->builddom();
3912 $mydom = $this->dom;
3913
3914 // Get question IDs
3915 $path = "//Question";
3916 $xpc = xpath_new_context($mydom);
3917 $res = &xpath_eval($xpc, $path);
3918
3919 $q_ids = array();
3920 include_once("./Services/Link/classes/class.ilInternalLink.php");
3921 for ($i = 0; $i < count($res->nodeset); $i++) {
3922 $qref = $res->nodeset[$i]->get_attribute("QRef");
3923
3924 $inst_id = ilInternalLink::_extractInstOfTarget($qref);
3926
3927 if (!($inst_id > 0)) {
3928 if ($obj_id > 0) {
3929 $q_ids[] = $obj_id;
3930 }
3931 }
3932 }
3933 return $q_ids;
3934 }
3935
3936 // @todo: move to paragraph
3937 public function send_paragraph($par_id, $filename)
3938 {
3939 $this->builddom();
3940
3941 $mydom = $this->dom;
3942
3943 $xpc = xpath_new_context($mydom);
3944
3945 //$path = "//PageContent[position () = $par_id]/Paragraph";
3946 //$path = "//Paragraph[$par_id]";
3947 $path = "/descendant::Paragraph[position() = $par_id]";
3948
3949 $res = &xpath_eval($xpc, $path);
3950
3951 if (count($res->nodeset) != 1) {
3952 die("Should not happen");
3953 }
3954
3955 $context_node = $res->nodeset[0];
3956
3957 // get plain text
3958
3959 $childs = $context_node->child_nodes();
3960
3961 for ($j=0; $j<count($childs); $j++) {
3962 $content .= $mydom->dump_node($childs[$j]);
3963 }
3964
3965 $content = str_replace("<br />", "\n", $content);
3966 $content = str_replace("<br/>", "\n", $content);
3967
3968 $plain_content = html_entity_decode($content);
3969
3970 ilUtil::deliverData($plain_content, $filename);
3971 /*
3972 $file_type = "application/octet-stream";
3973 header("Content-type: ".$file_type);
3974 header("Content-disposition: attachment; filename=\"$filename\"");
3975 echo $plain_content;*/
3976 exit();
3977 }
3978
3982 // @todo: deprecated?
3983 public function getFO()
3984 {
3985 $xml = $this->getXMLFromDom(false, true, true);
3986 $xsl = file_get_contents("./Services/COPage/xsl/page_fo.xsl");
3987 $args = array( '/_xml' => $xml, '/_xsl' => $xsl );
3988 $xh = xslt_create();
3989
3990 $params = array();
3991
3992
3993 $fo = xslt_process($xh, "arg:/_xml", "arg:/_xsl", null, $args, $params);
3994 var_dump($fo);
3995 // do some replacements
3996 $fo = str_replace("\n", "", $fo);
3997 $fo = str_replace("<br/>", "<br>", $fo);
3998 $fo = str_replace("<br>", "\n", $fo);
3999
4000 xslt_free($xh);
4001
4002 //
4003 $fo = substr($fo, strpos($fo, ">") + 1);
4004 //echo "<br><b>fo:</b><br>".htmlentities($fo); flush();
4005 return $fo;
4006 }
4007
4009 {
4010 $this->offline_handler = $handler;
4011 }
4012
4019 public function getOfflineHandler()
4020 {
4022 }
4023
4024
4028 public static function _lookupContainsDeactivatedElements($a_id, $a_parent_type, $a_lang = "-")
4029 {
4030 global $DIC;
4031
4032 $db = $DIC->database();
4033
4034 if ($a_lang == "") {
4035 $a_lang = "-";
4036 }
4037
4038 $query = "SELECT * FROM page_object WHERE page_id = " .
4039 $db->quote($a_id, "integer") . " AND " .
4040 " parent_type = " . $db->quote($a_parent_type, "text") . " AND " .
4041 " lang = " . $db->quote($a_lang, "text") . " AND " .
4042 " inactive_elements = " . $db->quote(1, "integer");
4043 $obj_set = $db->query($query);
4044
4045 if ($obj_rec = $obj_set->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) {
4046 return true;
4047 }
4048
4049 return false;
4050 }
4051
4059 {
4060 if (strpos($a_content, " Enabled=\"False\"")) {
4061 return true;
4062 }
4063 return false;
4064 }
4065
4069 public function getHistoryEntries()
4070 {
4071 $db = $this->db;
4072
4073 $h_query = "SELECT * FROM page_history " .
4074 " WHERE page_id = " . $db->quote($this->getId(), "integer") .
4075 " AND parent_type = " . $db->quote($this->getParentType(), "text") .
4076 " AND lang = " . $db->quote($this->getLanguage(), "text") .
4077 " ORDER BY hdate DESC";
4078
4079 $hset = $db->query($h_query);
4080 $hentries = array();
4081
4082 while ($hrec = $db->fetchAssoc($hset)) {
4083 $hrec["sortkey"] = (int) $hrec["nr"];
4084 $hrec["user"] = (int) $hrec["user_id"];
4085 $hentries[] = $hrec;
4086 }
4087 //var_dump($hentries);
4088 return $hentries;
4089 }
4090
4094 public function getHistoryEntry($a_old_nr)
4095 {
4096 $db = $this->db;
4097
4098 $res = $db->queryF(
4099 "SELECT * FROM page_history " .
4100 " WHERE page_id = %s " .
4101 " AND parent_type = %s " .
4102 " AND nr = %s" .
4103 " AND lang = %s",
4104 array("integer", "text", "integer", "text"),
4105 array($this->getId(), $this->getParentType(), $a_old_nr, $this->getLanguage())
4106 );
4107 if ($hrec = $db->fetchAssoc($res)) {
4108 return $hrec;
4109 }
4110
4111 return false;
4112 }
4113
4114
4121 public function getHistoryInfo($a_nr)
4122 {
4123 $db = $this->db;
4124
4125 // determine previous entry
4126 $and_nr = ($a_nr > 0)
4127 ? " AND nr < " . $db->quote((int) $a_nr, "integer")
4128 : "";
4129 $res = $db->query("SELECT MAX(nr) mnr FROM page_history " .
4130 " WHERE page_id = " . $db->quote($this->getId(), "integer") .
4131 " AND parent_type = " . $db->quote($this->getParentType(), "text") .
4132 " AND lang = " . $db->quote($this->getLanguage(), "text") .
4133 $and_nr);
4134 $row = $db->fetchAssoc($res);
4135 if ($row["mnr"] > 0) {
4136 $res = $db->query("SELECT * FROM page_history " .
4137 " WHERE page_id = " . $db->quote($this->getId(), "integer") .
4138 " AND parent_type = " . $db->quote($this->getParentType(), "text") .
4139 " AND lang = " . $db->quote($this->getLanguage(), "text") .
4140 " AND nr = " . $db->quote((int) $row["mnr"], "integer"));
4141 $row = $db->fetchAssoc($res);
4142 $ret["previous"] = $row;
4143 }
4144
4145 // determine next entry
4146 $res = $db->query("SELECT MIN(nr) mnr FROM page_history " .
4147 " WHERE page_id = " . $db->quote($this->getId(), "integer") .
4148 " AND parent_type = " . $db->quote($this->getParentType(), "text") .
4149 " AND lang = " . $db->quote($this->getLanguage(), "text") .
4150 " AND nr > " . $db->quote((int) $a_nr, "integer"));
4151 $row = $db->fetchAssoc($res);
4152 if ($row["mnr"] > 0) {
4153 $res = $db->query("SELECT * FROM page_history " .
4154 " WHERE page_id = " . $db->quote($this->getId(), "integer") .
4155 " AND parent_type = " . $db->quote($this->getParentType(), "text") .
4156 " AND lang = " . $db->quote($this->getLanguage(), "text") .
4157 " AND nr = " . $db->quote((int) $row["mnr"], "integer"));
4158 $row = $db->fetchAssoc($res);
4159 $ret["next"] = $row;
4160 }
4161
4162 // current
4163 if ($a_nr > 0) {
4164 $res = $db->query("SELECT * FROM page_history " .
4165 " WHERE page_id = " . $db->quote($this->getId(), "integer") .
4166 " AND parent_type = " . $db->quote($this->getParentType(), "text") .
4167 " AND lang = " . $db->quote($this->getLanguage(), "text") .
4168 " AND nr = " . $db->quote((int) $a_nr, "integer"));
4169 $row = $db->fetchAssoc($res);
4170 } else {
4171 $res = $db->query("SELECT page_id, last_change hdate, parent_type, parent_id, last_change_user user_id, content, lang FROM page_object " .
4172 " WHERE page_id = " . $db->quote($this->getId(), "integer") .
4173 " AND parent_type = " . $db->quote($this->getParentType(), "text") .
4174 " AND lang = " . $db->quote($this->getLanguage(), "text"));
4175 $row = $db->fetchAssoc($res);
4176 }
4177 $ret["current"] = $row;
4178
4179 return $ret;
4180 }
4181
4182 public function addChangeDivClasses($a_hashes)
4183 {
4184 $xpc = xpath_new_context($this->dom);
4185 $path = "/*[1]";
4186 $res = xpath_eval($xpc, $path);
4187 $rnode = $res->nodeset[0];
4188
4189 //echo "A";
4190 foreach ($a_hashes as $pc_id => $h) {
4191 //echo "B";
4192 if ($h["change"] != "") {
4193 $dc_node = $this->dom->create_element("DivClass");
4194 $dc_node->set_attribute("HierId", $h["hier_id"]);
4195 $dc_node->set_attribute("Class", "ilEdit" . $h["change"]);
4196 $dc_node = $rnode->append_child($dc_node);
4197 }
4198 }
4199 //echo "<br><br><br><br><br><br>".htmlentities($this->getXMLFromDom());
4200 }
4201
4208 public function compareVersion($a_left, $a_right)
4209 {
4210 // get page objects
4211 include_once("./Services/COPage/classes/class.ilPageObjectFactory.php");
4212 $l_page = ilPageObjectFactory::getInstance($this->getParentType(), $this->getId(), $a_left);
4213 $r_page = ilPageObjectFactory::getInstance($this->getParentType(), $this->getId(), $a_right);
4214
4215 $l_hashes = $l_page->getPageContentsHashes();
4216 $r_hashes = $r_page->getPageContentsHashes();
4217 // determine all deleted and changed page elements
4218 foreach ($l_hashes as $pc_id => $h) {
4219 if (!isset($r_hashes[$pc_id])) {
4220 $l_hashes[$pc_id]["change"] = "Deleted";
4221 } else {
4222 if ($l_hashes[$pc_id]["hash"] != $r_hashes[$pc_id]["hash"]) {
4223 $l_hashes[$pc_id]["change"] = "Modified";
4224 $r_hashes[$pc_id]["change"] = "Modified";
4225
4226 include_once("./Services/COPage/mediawikidiff/class.WordLevelDiff.php");
4227 // if modified element is a paragraph, highlight changes
4228 if ($l_hashes[$pc_id]["content"] != "" &&
4229 $r_hashes[$pc_id]["content"] != "") {
4230 $new_left = str_replace("\n", "<br />", $l_hashes[$pc_id]["content"]);
4231 $new_right = str_replace("\n", "<br />", $r_hashes[$pc_id]["content"]);
4232 $wldiff = new WordLevelDiff(
4233 array($new_left),
4234 array($new_right)
4235 );
4236 $new_left = $wldiff->orig();
4237 $new_right = $wldiff->closing();
4238 $l_page->setParagraphContent($l_hashes[$pc_id]["hier_id"], $new_left[0]);
4239 $r_page->setParagraphContent($l_hashes[$pc_id]["hier_id"], $new_right[0]);
4240 }
4241 }
4242 }
4243 }
4244
4245 // determine all new paragraphs
4246 foreach ($r_hashes as $pc_id => $h) {
4247 if (!isset($l_hashes[$pc_id])) {
4248 $r_hashes[$pc_id]["change"] = "New";
4249 }
4250 }
4251 $l_page->addChangeDivClasses($l_hashes);
4252 $r_page->addChangeDivClasses($r_hashes);
4253
4254 return array("l_page" => $l_page, "r_page" => $r_page,
4255 "l_changes" => $l_hashes, "r_changes" => $r_hashes);
4256 }
4257
4261 public function increaseViewCnt()
4262 {
4263 $db = $this->db;
4264
4265 $db->manipulate("UPDATE page_object " .
4266 " SET view_cnt = view_cnt + 1 " .
4267 " WHERE page_id = " . $db->quote($this->getId(), "integer") .
4268 " AND parent_type = " . $db->quote($this->getParentType(), "text") .
4269 " AND lang = " . $db->quote($this->getLanguage(), "text"));
4270 }
4271
4279 public static function getRecentChanges($a_parent_type, $a_parent_id, $a_period = 30, $a_lang = "")
4280 {
4281 global $DIC;
4282
4283 $db = $DIC->database();
4284
4285 $and_lang = "";
4286 if ($a_lang != "") {
4287 $and_lang = " AND lang = " . $db->quote($a_lang, "text");
4288 }
4289
4290 $page_changes = array();
4291 $limit_ts = date('Y-m-d H:i:s', time() - ($a_period * 24 * 60 * 60));
4292 $q = "SELECT * FROM page_object " .
4293 " WHERE parent_id = " . $db->quote($a_parent_id, "integer") .
4294 " AND parent_type = " . $db->quote($a_parent_type, "text") .
4295 " AND last_change >= " . $db->quote($limit_ts, "timestamp") . $and_lang;
4296 // " AND (TO_DAYS(now()) - TO_DAYS(last_change)) <= ".((int)$a_period);
4297 $set = $db->query($q);
4298 while ($page = $db->fetchAssoc($set)) {
4299 $page_changes[] = array(
4300 "date" => $page["last_change"],
4301 "id" => $page["page_id"],
4302 "lang" => $page["lang"],
4303 "type" => "page",
4304 "user" => $page["last_change_user"]);
4305 }
4306
4307 $and_str = "";
4308 if ($a_period > 0) {
4309 $limit_ts = date('Y-m-d H:i:s', time() - ($a_period * 24 * 60 * 60));
4310 $and_str = " AND hdate >= " . $db->quote($limit_ts, "timestamp") . " ";
4311 }
4312
4313 $q = "SELECT * FROM page_history " .
4314 " WHERE parent_id = " . $db->quote($a_parent_id, "integer") .
4315 " AND parent_type = " . $db->quote($a_parent_type, "text") .
4316 $and_str . $and_lang;
4317 $set = $db->query($q);
4318 while ($page = $db->fetchAssoc($set)) {
4319 $page_changes[] = array(
4320 "date" => $page["hdate"],
4321 "id" => $page["page_id"],
4322 "lang" => $page["lang"],
4323 "type" => "hist",
4324 "nr" => $page["nr"],
4325 "user" => $page["user_id"]);
4326 }
4327
4328 $page_changes = ilUtil::sortArray($page_changes, "date", "desc");
4329
4330 return $page_changes;
4331 }
4332
4341 public static function getAllPages($a_parent_type, $a_parent_id, $a_lang = "-")
4342 {
4343 global $DIC;
4344
4345 $db = $DIC->database();
4346
4347 $and_lang = "";
4348 if ($a_lang != "") {
4349 $and_lang = " AND lang = " . $db->quote($a_lang, "text");
4350 }
4351
4352 $q = "SELECT * FROM page_object " .
4353 " WHERE parent_id = " . $db->quote($a_parent_id, "integer") .
4354 " AND parent_type = " . $db->quote($a_parent_type, "text") . $and_lang;
4355 $set = $db->query($q);
4356 $pages = array();
4357 while ($page = $db->fetchAssoc($set)) {
4358 $key_add = ($a_lang == "")
4359 ? ":" . $page["lang"]
4360 : "";
4361 $pages[$page["page_id"] . $key_add] = array(
4362 "date" => $page["last_change"],
4363 "id" => $page["page_id"],
4364 "lang" => $page["lang"],
4365 "user" => $page["last_change_user"]);
4366 }
4367
4368 return $pages;
4369 }
4370
4377 public static function getNewPages($a_parent_type, $a_parent_id, $a_lang = "-")
4378 {
4379 global $DIC;
4380
4381 $db = $DIC->database();
4382
4383 $and_lang = "";
4384 if ($a_lang != "") {
4385 $and_lang = " AND lang = " . $db->quote($a_lang, "text");
4386 }
4387
4388 $pages = array();
4389
4390 $q = "SELECT * FROM page_object " .
4391 " WHERE parent_id = " . $db->quote($a_parent_id, "integer") .
4392 " AND parent_type = " . $db->quote($a_parent_type, "text") . $and_lang .
4393 " ORDER BY created DESC";
4394 $set = $db->query($q);
4395 while ($page = $db->fetchAssoc($set)) {
4396 if ($page["created"] != "") {
4397 $pages[] = array(
4398 "created" => $page["created"],
4399 "id" => $page["page_id"],
4400 "lang" => $page["lang"],
4401 "user" => $page["create_user"],
4402 );
4403 }
4404 }
4405
4406 return $pages;
4407 }
4408
4415 public static function getParentObjectContributors($a_parent_type, $a_parent_id, $a_lang = "-")
4416 {
4417 global $DIC;
4418
4419 $db = $DIC->database();
4420
4421 $and_lang = "";
4422 if ($a_lang != "") {
4423 $and_lang = " AND lang = " . $db->quote($a_lang, "text");
4424 }
4425
4426 $contributors = array();
4427 $set = $db->queryF(
4428 "SELECT last_change_user, lang, page_id FROM page_object " .
4429 " WHERE parent_id = %s AND parent_type = %s " .
4430 " AND last_change_user != %s" . $and_lang,
4431 array("integer", "text", "integer"),
4432 array($a_parent_id, $a_parent_type, 0)
4433 );
4434
4435 while ($page = $db->fetchAssoc($set)) {
4436 if ($a_lang == "") {
4437 $contributors[$page["last_change_user"]][$page["page_id"]][$page["lang"]] = 1;
4438 } else {
4439 $contributors[$page["last_change_user"]][$page["page_id"]] = 1;
4440 }
4441 }
4442
4443 $set = $db->queryF(
4444 "SELECT count(*) as cnt, lang, page_id, user_id FROM page_history " .
4445 " WHERE parent_id = %s AND parent_type = %s AND user_id != %s " . $and_lang .
4446 " GROUP BY page_id, user_id, lang ",
4447 array("integer", "text", "integer"),
4448 array($a_parent_id, $a_parent_type, 0)
4449 );
4450 while ($hpage = $db->fetchAssoc($set)) {
4451 if ($a_lang == "") {
4452 $contributors[$hpage["user_id"]][$hpage["page_id"]][$hpage["lang"]] =
4453 $contributors[$hpage["user_id"]][$hpage["page_id"]][$hpage["lang"]] + $hpage["cnt"];
4454 } else {
4455 $contributors[$hpage["user_id"]][$hpage["page_id"]] =
4456 $contributors[$hpage["user_id"]][$hpage["page_id"]] + $hpage["cnt"];
4457 }
4458 }
4459
4460 $c = array();
4461 foreach ($contributors as $k => $co) {
4462 if (ilObject::_lookupType($k) == "usr") {
4464 $c[] = array("user_id" => $k, "pages" => $co,
4465 "lastname" => $name["lastname"], "firstname" => $name["firstname"]);
4466 }
4467 }
4468
4469 return $c;
4470 }
4471
4478 public static function getPageContributors($a_parent_type, $a_page_id, $a_lang = "-")
4479 {
4480 global $DIC;
4481
4482 $db = $DIC->database();
4483
4484 $and_lang = "";
4485 if ($a_lang != "") {
4486 $and_lang = " AND lang = " . $db->quote($a_lang, "text");
4487 }
4488
4489 $contributors = array();
4490 $set = $db->queryF(
4491 "SELECT last_change_user, lang FROM page_object " .
4492 " WHERE page_id = %s AND parent_type = %s " .
4493 " AND last_change_user != %s" . $and_lang,
4494 array("integer", "text", "integer"),
4495 array($a_page_id, $a_parent_type, 0)
4496 );
4497
4498 while ($page = $db->fetchAssoc($set)) {
4499 if ($a_lang == "") {
4500 $contributors[$page["last_change_user"]][$page["lang"]] = 1;
4501 } else {
4502 $contributors[$page["last_change_user"]] = 1;
4503 }
4504 }
4505
4506 $set = $db->queryF(
4507 "SELECT count(*) as cnt, lang, page_id, user_id FROM page_history " .
4508 " WHERE page_id = %s AND parent_type = %s AND user_id != %s " . $and_lang .
4509 " GROUP BY user_id, page_id, lang ",
4510 array("integer", "text", "integer"),
4511 array($a_page_id, $a_parent_type, 0)
4512 );
4513 while ($hpage = $db->fetchAssoc($set)) {
4514 if ($a_lang == "") {
4515 $contributors[$hpage["user_id"]][$page["lang"]] =
4516 $contributors[$hpage["user_id"]][$page["lang"]] + $hpage["cnt"];
4517 } else {
4518 $contributors[$hpage["user_id"]] =
4519 $contributors[$hpage["user_id"]] + $hpage["cnt"];
4520 }
4521 }
4522
4523 $c = array();
4524 foreach ($contributors as $k => $co) {
4525 include_once "Services/User/classes/class.ilObjUser.php";
4527 $c[] = array("user_id" => $k, "pages" => $co,
4528 "lastname" => $name["lastname"], "firstname" => $name["firstname"]);
4529 }
4530
4531 return $c;
4532 }
4533
4537 public function writeRenderedContent($a_content, $a_md5)
4538 {
4539 global $DIC;
4540
4541 $db = $DIC->database();
4542
4543 $db->update("page_object", array(
4544 "rendered_content" => array("clob", $a_content),
4545 "render_md5" => array("text", $a_md5),
4546 "rendered_time" => array("timestamp", ilUtil::now())
4547 ), array(
4548 "page_id" => array("integer", $this->getId()),
4549 "lang" => array("text", $this->getLanguage()),
4550 "parent_type" => array("text", $this->getParentType())
4551 ));
4552 }
4553
4561 public static function getPagesWithLinks($a_parent_type, $a_parent_id, $a_lang = "-")
4562 {
4563 global $DIC;
4564
4565 $db = $DIC->database();
4566
4567 $and_lang = "";
4568 if ($a_lang != "") {
4569 $and_lang = " AND lang = " . $db->quote($a_lang, "text");
4570 }
4571
4572 $q = "SELECT * FROM page_object " .
4573 " WHERE parent_id = " . $db->quote($a_parent_id, "integer") .
4574 " AND parent_type = " . $db->quote($a_parent_type, "text") .
4575 " AND int_links = " . $db->quote(1, "integer") . $and_lang;
4576 $set = $db->query($q);
4577 $pages = array();
4578 while ($page = $db->fetchAssoc($set)) {
4579 $key_add = ($a_lang == "")
4580 ? ":" . $page["lang"]
4581 : "";
4582 $pages[$page["page_id"] . $key_add] = array(
4583 "date" => $page["last_change"],
4584 "id" => $page["page_id"],
4585 "lang" => $page["lang"],
4586 "user" => $page["last_change_user"]);
4587 }
4588
4589 return $pages;
4590 }
4591
4599 {
4600 if (strpos($a_content, "IntLink")) {
4601 return true;
4602 }
4603 return false;
4604 }
4605
4610 {
4611 }
4612
4618 // @todo begin: generalize
4619 public function saveInitialOpenedContent($a_type, $a_id, $a_target)
4620 {
4621 $this->buildDom();
4622
4623 $link_type = "";
4624
4625 switch ($a_type) {
4626 case "media":
4627 $link_type = "MediaObject";
4628 $a_id = "il__mob_" . $a_id;
4629 break;
4630
4631 case "page":
4632 $link_type = "PageObject";
4633 $a_id = "il__pg_" . $a_id;
4634 break;
4635
4636 case "term":
4637 $link_type = "GlossaryItem";
4638 $a_id = "il__git_" . $a_id;
4639 $a_target = "Glossary";
4640 break;
4641 }
4642
4643 // if type or id missing -> delete InitOpenedContent, if existing
4644 if ($link_type == "" || $a_id == "") {
4645 $xpc = xpath_new_context($this->dom);
4646 $path = "//PageObject/InitOpenedContent";
4647 $res = xpath_eval($xpc, $path);
4648 if (count($res->nodeset) > 0) {
4649 $res->nodeset[0]->unlink_node($res->nodeset[0]);
4650 }
4651 } else {
4652 $xpc = xpath_new_context($this->dom);
4653 $path = "//PageObject/InitOpenedContent";
4654 $res = xpath_eval($xpc, $path);
4655 if (count($res->nodeset) > 0) {
4656 $init_node = $res->nodeset[0];
4657 $childs = $init_node->child_nodes();
4658 for ($i = 0; $i < count($childs); $i++) {
4659 if ($childs[$i]->node_name() == "IntLink") {
4660 $il_node = $childs[$i];
4661 }
4662 }
4663 } else {
4664 $path = "//PageObject";
4665 $res = xpath_eval($xpc, $path);
4666 $page_node = $res->nodeset[0];
4667 $init_node = $this->dom->create_element("InitOpenedContent");
4668 $init_node = $page_node->append_child($init_node);
4669 $il_node = $this->dom->create_element("IntLink");
4670 $il_node = $init_node->append_child($il_node);
4671 }
4672 $il_node->set_attribute("Target", $a_id);
4673 $il_node->set_attribute("Type", $link_type);
4674 $il_node->set_attribute("TargetFrame", $a_target);
4675 }
4676
4677 $this->update();
4678 }
4679
4680
4686 public function getInitialOpenedContent()
4687 {
4688 $this->buildDom();
4689
4690 $xpc = xpath_new_context($this->dom);
4691 $path = "//PageObject/InitOpenedContent";
4692 $res = xpath_eval($xpc, $path);
4693 $il_node = null;
4694 if (count($res->nodeset) > 0) {
4695 $init_node = $res->nodeset[0];
4696 $childs = $init_node->child_nodes();
4697 for ($i = 0; $i < count($childs); $i++) {
4698 if ($childs[$i]->node_name() == "IntLink") {
4699 $il_node = $childs[$i];
4700 }
4701 }
4702 }
4703 if (!is_null($il_node)) {
4704 $id = $il_node->get_attribute("Target");
4705 $link_type = $il_node->get_attribute("Type");
4706 $target = $il_node->get_attribute("TargetFrame");
4707
4708 switch ($link_type) {
4709 case "MediaObject":
4710 $type = "media";
4711 break;
4712
4713 case "PageObject":
4714 $type = "page";
4715 break;
4716
4717 case "GlossaryItem":
4718 $type = "term";
4719 break;
4720 }
4721 include_once("./Services/Link/classes/class.ilInternalLink.php");
4723 return array("id" => $id, "type" => $type, "target" => $target);
4724 }
4725
4726 return array();
4727 }
4728 // @todo end
4729
4740 public function beforePageContentUpdate($a_page_content)
4741 {
4742 }
4743
4751 public function copy($a_id, $a_parent_type = "", $a_parent_id = 0, $a_clone_mobs = false)
4752 {
4753 if ($a_parent_type == "") {
4754 $a_parent_type = $this->getParentType();
4755 if ($a_parent_id == 0) {
4756 $a_parent_id = $this->getParentId();
4757 }
4758 }
4759
4760 include_once("./Services/COPage/classes/class.ilPageObjectFactory.php");
4761 foreach (self::lookupTranslations($this->getParentType(), $this->getId()) as $l) {
4762 $existed = false;
4763 $orig_page = ilPageObjectFactory::getInstance($this->getParentType(), $this->getId(), 0, $l);
4764 if (ilPageObject::_exists($a_parent_type, $a_id, $l)) {
4765 $new_page_object = ilPageObjectFactory::getInstance($a_parent_type, $a_id, 0, $l);
4766 $existed = true;
4767 } else {
4768 $new_page_object = ilPageObjectFactory::getInstance($a_parent_type, 0, 0, $l);
4769 $new_page_object->setParentId($a_parent_id);
4770 $new_page_object->setId($a_id);
4771 }
4772 $new_page_object->setXMLContent($orig_page->copyXMLContent($a_clone_mobs));
4773 $new_page_object->setActive($orig_page->getActive());
4774 $new_page_object->setActivationStart($orig_page->getActivationStart());
4775 $new_page_object->setActivationEnd($orig_page->getActivationEnd());
4776 if ($existed) {
4777 $new_page_object->buildDom();
4778 $new_page_object->update();
4779 } else {
4780 $new_page_object->create();
4781 }
4782 }
4783 }
4784
4792 public static function lookupTranslations($a_parent_type, $a_id)
4793 {
4794 global $DIC;
4795
4796 $db = $DIC->database();
4797
4798 $set = $db->query(
4799 "SELECT lang FROM page_object " .
4800 " WHERE page_id = " . $db->quote($a_id, "integer") .
4801 " AND parent_type = " . $db->quote($a_parent_type, "text")
4802 );
4803 $langs = array();
4804 while ($rec = $db->fetchAssoc($set)) {
4805 $langs[] = $rec["lang"];
4806 }
4807 return $langs;
4808 }
4809
4810
4816 public function copyPageToTranslation($a_target_lang)
4817 {
4818 $transl_page = ilPageObjectFactory::getInstance(
4819 $this->getParentType(),
4820 0,
4821 0,
4822 $a_target_lang
4823 );
4824 $transl_page->setId($this->getId());
4825 $transl_page->setParentId($this->getParentId());
4826 $transl_page->setXMLContent($this->copyXMLContent());
4827 $transl_page->setActive($this->getActive());
4828 $transl_page->setActivationStart($this->getActivationStart());
4829 $transl_page->setActivationEnd($this->getActivationEnd());
4830 $transl_page->create();
4831 }
4832
4836
4840 public function getEditLock()
4841 {
4842 $db = $this->db;
4844
4845 $min = (int) $this->getEffectiveEditLockTime();
4846 if ($min > 0) {
4847 // try to set the lock for the user
4848 $ts = time();
4849 $db->manipulate(
4850 "UPDATE page_object SET " .
4851 " edit_lock_user = " . $db->quote($user->getId(), "integer") . "," .
4852 " edit_lock_ts = " . $db->quote($ts, "integer") .
4853 " WHERE (edit_lock_user = " . $db->quote($user->getId(), "integer") . " OR " .
4854 " edit_lock_ts < " . $db->quote(time() - ($min * 60), "integer") . ") " .
4855 " AND page_id = " . $db->quote($this->getId(), "integer") .
4856 " AND parent_type = " . $db->quote($this->getParentType(), "text")
4857 );
4858
4859 $set = $db->query(
4860 "SELECT edit_lock_user FROM page_object " .
4861 " WHERE page_id = " . $db->quote($this->getId(), "integer") .
4862 " AND parent_type = " . $db->quote($this->getParentType(), "text")
4863 );
4864 $rec = $db->fetchAssoc($set);
4865 if ($rec["edit_lock_user"] != $user->getId()) {
4866 return false;
4867 }
4868 }
4869
4870 return true;
4871 }
4872
4876 public function releasePageLock()
4877 {
4878 $db = $this->db;
4880 $aset = new ilSetting("adve");
4881
4882 $min = (int) $aset->get("block_mode_minutes") ;
4883 if ($min > 0) {
4884 // try to set the lock for the user
4885 $ts = time();
4886 $db->manipulate(
4887 "UPDATE page_object SET " .
4888 " edit_lock_user = " . $db->quote($user->getId(), "integer") . "," .
4889 " edit_lock_ts = 0" .
4890 " WHERE edit_lock_user = " . $db->quote($user->getId(), "integer") .
4891 " AND page_id = " . $db->quote($this->getId(), "integer") .
4892 " AND parent_type = " . $db->quote($this->getParentType(), "text")
4893 );
4894
4895 $set = $db->query(
4896 "SELECT edit_lock_user FROM page_object " .
4897 " WHERE page_id = " . $db->quote($this->getId(), "integer") .
4898 " AND parent_type = " . $db->quote($this->getParentType(), "text")
4899 );
4900 $rec = $db->fetchAssoc($set);
4901 if ($rec["edit_lock_user"] != $user->getId()) {
4902 return false;
4903 }
4904 }
4905
4906 return true;
4907 }
4908
4914 public function getEditLockInfo()
4915 {
4916 $db = $this->db;
4917
4918 $aset = new ilSetting("adve");
4919 $min = (int) $aset->get("block_mode_minutes");
4920
4921 $set = $db->query(
4922 "SELECT edit_lock_user, edit_lock_ts FROM page_object " .
4923 " WHERE page_id = " . $db->quote($this->getId(), "integer") .
4924 " AND parent_type = " . $db->quote($this->getParentType(), "text")
4925 );
4926 $rec = $db->fetchAssoc($set);
4927 $rec["edit_lock_until"] = $rec["edit_lock_ts"] + $min * 60;
4928
4929 return $rec;
4930 }
4931
4944 public static function truncateHTML($a_text, $a_length = 100, $a_ending = '...', $a_exact = false, $a_consider_html = true)
4945 {
4946 include_once "Services/Utilities/classes/class.ilStr.php";
4947
4948 if ($a_consider_html) {
4949 // if the plain text is shorter than the maximum length, return the whole text
4950 if (strlen(preg_replace('/<.*?>/', '', $a_text)) <= $a_length) {
4951 return $a_text;
4952 }
4953
4954 // splits all html-tags to scanable lines
4955 $total_length = strlen($a_ending);
4956 $open_tags = array();
4957 $truncate = '';
4958 preg_match_all('/(<.+?>)?([^<>]*)/s', $a_text, $lines, PREG_SET_ORDER);
4959 foreach ($lines as $line_matchings) {
4960 // if there is any html-tag in this line, handle it and add it (uncounted) to the output
4961 if (!empty($line_matchings[1])) {
4962 // if it's an "empty element" with or without xhtml-conform closing slash
4963 if (preg_match('/^<(\s*.+?\/\s*|\s*(img|br|input|hr|area|base|basefont|col|frame|isindex|link|meta|param)(\s.+?)?)>$/is', $line_matchings[1])) {
4964 // do nothing
4965 }
4966 // if tag is a closing tag
4967 elseif (preg_match('/^<\s*\/([^\s]+?)\s*>$/s', $line_matchings[1], $tag_matchings)) {
4968 // delete tag from $open_tags list
4969 $pos = array_search($tag_matchings[1], $open_tags);
4970 if ($pos !== false) {
4971 unset($open_tags[$pos]);
4972 }
4973 }
4974 // if tag is an opening tag
4975 elseif (preg_match('/^<\s*([^\s>!]+).*?>$/s', $line_matchings[1], $tag_matchings)) {
4976 // add tag to the beginning of $open_tags list
4977 array_unshift($open_tags, strtolower($tag_matchings[1]));
4978 }
4979 // add html-tag to $truncate'd text
4980 $truncate .= $line_matchings[1];
4981 }
4982
4983 // calculate the length of the plain text part of the line; handle entities as one character
4984 $content_length = strlen(preg_replace('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|[0-9a-f]{1,6};/i', ' ', $line_matchings[2]));
4985 if ($total_length+$content_length > $a_length) {
4986 // the number of characters which are left
4987 $left = $a_length - $total_length;
4988 $entities_length = 0;
4989 // search for html entities
4990 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)) {
4991 // calculate the real length of all entities in the legal range
4992 foreach ($entities[0] as $entity) {
4993 if ($entity[1]+1-$entities_length <= $left) {
4994 $left--;
4995 $entities_length += strlen($entity[0]);
4996 } else {
4997 // no more characters left
4998 break;
4999 }
5000 }
5001 }
5002
5003 // $truncate .= substr($line_matchings[2], 0, $left+$entities_length);
5004 $truncate .= ilStr::shortenText($line_matchings[2], 0, $left+$entities_length);
5005
5006 // maximum lenght is reached, so get off the loop
5007 break;
5008 } else {
5009 $truncate .= $line_matchings[2];
5010 $total_length += $content_length;
5011 }
5012
5013 // if the maximum length is reached, get off the loop
5014 if ($total_length >= $a_length) {
5015 break;
5016 }
5017 }
5018 } else {
5019 if (strlen($a_text) <= $a_length) {
5020 return $a_text;
5021 } else {
5022 // $truncate = substr($a_text, 0, $a_length - strlen($a_ending));
5023 $truncate = ilStr::shortenText($a_text, 0, $a_length - strlen($a_ending));
5024 }
5025 }
5026
5027 // THIS IS BUGGY AS IT MIGHT BREAK AN OPEN TAG AT THE END
5028 if (!sizeof($open_tags)) {
5029 // if the words shouldn't be cut in the middle...
5030 if (!$a_exact) {
5031 // ...search the last occurance of a space...
5032 $spacepos = strrpos($truncate, ' ');
5033 if ($spacepos !== false) {
5034 // ...and cut the text in this position
5035 // $truncate = substr($truncate, 0, $spacepos);
5036 $truncate = ilStr::shortenText($truncate, 0, $spacepos);
5037 }
5038 }
5039 }
5040
5041 // add the defined ending to the text
5042 $truncate .= $a_ending;
5043
5044 if ($a_consider_html) {
5045 // close all unclosed html-tags
5046 foreach ($open_tags as $tag) {
5047 $truncate .= '</' . $tag . '>';
5048 }
5049 }
5050
5051 return $truncate;
5052 }
5053
5059 public function getContentTemplates()
5060 {
5061 return array();
5062 }
5063
5071 public static function getLastChangeByParent($a_parent_type, $a_parent_id, $a_lang = "")
5072 {
5073 global $DIC;
5074
5075 $db = $DIC->database();
5076
5077 $and_lang = "";
5078 if ($a_lang != "") {
5079 $and_lang = " AND lang = " . $db->quote($a_lang, "text");
5080 }
5081
5082 $db->setLimit(1);
5083 $q = "SELECT last_change FROM page_object " .
5084 " WHERE parent_id = " . $db->quote($a_parent_id, "integer") .
5085 " AND parent_type = " . $db->quote($a_parent_type, "text") . $and_lang .
5086 " ORDER BY last_change DESC";
5087
5088 $set = $db->query($q);
5089 $rec = $db->fetchAssoc($set);
5090
5091 return $rec["last_change"];
5092 }
5093
5095 {
5096 if ($this->getPageConfig()->getEditLockSupport() == false) {
5097 return 0;
5098 }
5099
5100 $aset = new ilSetting("adve");
5101 $min = (int) $aset->get("block_mode_minutes") ;
5102
5103 return $min;
5104 }
5105
5111 public function getAllFileObjIds()
5112 {
5113 $file_obj_ids = array();
5114
5115 // insert inst id file item identifier entries
5116 $xpc = xpath_new_context($this->dom);
5117 $path = "//FileItem/Identifier";
5118 $res = xpath_eval($xpc, $path);
5119 for ($i = 0; $i < count($res->nodeset); $i++) {
5120 $file_obj_ids[] = $res->nodeset[$i]->get_attribute("Entry");
5121 }
5122 unset($xpc);
5123 return $file_obj_ids;
5124 }
5125
5130 public function resolveResources($ref_mapping)
5131 {
5132 include_once("./Services/COPage/classes/class.ilPCResources.php");
5133 return ilPCResources::resolveResources($this, $ref_mapping);
5134 }
5135}
date( 'd-M-Y', $objPHPExcel->getProperties() ->getCreated())
user()
Definition: user.php:4
$size
Definition: RandomTest.php:84
$files
Definition: add-vimline.php:18
global $l
Definition: afr.php:30
if(!isset( $_REQUEST[ 'ReturnTo'])) if(!isset($_REQUEST['AuthId'])) $options
Definition: as_login.php:20
$source
Definition: linkback.php:22
$_GET["client_id"]
$_POST["username"]
An exception for terminatinating execution or to throw for unit testing.
const IL_CAL_UNIX
const IL_CAL_DATETIME
const IL_MODE_OUTPUT
const IL_INSERT_BEFORE
const IL_INSERT_CHILD
const IL_INSERT_AFTER
static _instantiateQuestion($question_id)
static getPCDefinitions()
Get PC definitions.
static getPCDefinitionByName($a_pc_name)
Get PC definition by name.
static requirePCClassByName($a_name)
Get instance.
static formatDate(ilDateTime $date, $a_skip_day=false, $a_include_wd=false)
Format a date @access public.
@classDescription Date and time handling
static _after(ilDateTime $start, ilDateTime $end, $a_compare_field='', $a_tz='')
compare two dates and check start is after end This method does not consider tz offsets.
static _before(ilDateTime $start, ilDateTime $end, $a_compare_field='', $a_tz='')
compare two dates and check start is before end This method does not consider tz offsets.
static setAction($a_action)
static _lookupType($a_obj_id, $a_lm_id=0)
Lookup type.
Extension of ilPageObject for learning modules.
static getLogger($a_component_id)
Get component logger.
Class ilMediaAliasItem.
static _resolveMapAreaLinks($a_mob_id)
resolve internal links of all media items of a media object
static _getMapAreasIntLinks($a_mob_id)
get all internal links of map areas of a mob
static deleteNewsOfContext( $a_context_obj_id, $a_context_obj_type, $a_context_sub_obj_id=0, $a_context_sub_obj_type="")
Delete all news of a context.
static _lookupFileSize($a_id)
Lookups the file size of the file in bytes.
static _getFilesOfObject($a_type, $a_id, $a_usage_hist_nr=0, $a_usage_lang="-")
get all files of an object
Class ilObjMediaObject.
static _deleteAllUsages($a_type, $a_id, $a_usage_hist_nr=0, $a_lang="-")
static
static _getMobsOfObject($a_type, $a_id, $a_usage_hist_nr=0, $a_lang="-")
get mobs of object
static _lookupName($a_user_id)
lookup user name
static _lookupObjId($a_id)
static _lookupImportId($a_obj_id)
static _exists($a_id, $a_reference=false, $a_type=null)
checks if an object exists in object_data@access public
static _getLastUpdateOfObjects($a_objs)
Get last update for a set of media objects.
static _lookupType($a_id, $a_reference=false)
lookup object type
Class ilPCDataTable.
Class ilPCMediaObject.
Class ilPCParagraph.
static xml2output($a_text, $a_wysiwyg=false, $a_replace_lists=true, $unmask=true)
Converts xml from DB to output in edit textarea.
static resolveResources(ilPageObject $page, $ref_mappings)
Resolve resources.
Class ilPCTable.
static incEdId($ed_id)
Increases an hierarchical editing id at lowest level (last number)
static sortHierIds($a_array)
Sort an array of Hier IDS in ascending order.
static getInstance($a_parent_type, $a_id=0, $a_old_nr=0, $a_lang="-")
Get page object instance.
static getConfigInstance($a_parent_type)
Get page config instance.
Class ilPageObject.
releasePageLock()
Release page lock.
stripHierIDs()
strip all hierarchical id attributes out of the dom tree
switchEnableMultiple($a_hids, $a_update=true, $a_self_ass=false)
(De-)activate elements
moveContentBefore($a_source, $a_target, $a_spcid="", $a_tpcid="")
move content object from position $a_source before position $a_target (both hierarchical content ids)
getEditLockInfo()
Get edit lock info.
getRenderedContent()
Get Rendered Content.
resolveResources($ref_mapping)
Resolve resources.
removeQuestions(&$temp_dom)
Remove questions from document.
setRenderedContent($a_renderedcontent)
Set Rendered Content.
getOfflineHandler()
Get offline handler.
__beforeDelete()
Before deletion handler (internal).
static truncateHTML($a_text, $a_length=100, $a_ending='...', $a_exact=false, $a_consider_html=true)
Truncate (html) string.
getRenderMd5()
Get Render MD5.
deleteStyleUsages($a_old_nr=0)
Delete style usages.
__construct($a_id=0, $a_old_nr=0, $a_lang="-")
Constructor @access public.
initPageConfig()
Init page config.
read()
Read page data.
getLastChangeUser()
Get last change user.
containsIntLinks($a_content)
Check whether content contains internal links.
static getPageContributors($a_parent_type, $a_page_id, $a_lang="-")
Get all contributors for parent object.
registerOfflineHandler($handler)
static getNewPages($a_parent_type, $a_parent_id, $a_lang="-")
Get new pages.
static _existsAndNotEmpty($a_parent_type, $a_id, $a_lang="-")
Checks whether page exists and is not empty (may return true on some empty pages)
getFirstColumnIds()
get ids of all first table columns
setActivationEnd($a_activationend)
Set Activation End.
getHistoryInfo($a_nr)
Get information about a history entry, its predecessor and its successor.
saveInitialOpenedContent($a_type, $a_id, $a_target)
Save initial opened content.
addFileSizes()
add file sizes
deleteInternalLinks()
Delete internal links.
deleteContent($a_hid, $a_update=true, $a_pcid="")
delete content object with hierarchical id $a_hid
static _lookupActive($a_id, $a_parent_type, $a_check_scheduled_activation=false, $a_lang="-")
lookup activation status
getLanguage()
Get language.
getPageConfig()
Get page config object.
setContainsIntLink($a_contains_link)
lm parser set this flag to true, if the page contains intern links (this method should only be called...
pasteContents($a_hier_id, $a_self_ass=false)
Paste contents from pc clipboard.
__afterHistoryEntry($a_old_domdoc, $a_old_content, $a_old_nr)
Before deletion handler (internal).
getEditLock()
Get page lock.
setImportMode($a_val)
Set import mode.
addUpdateListener(&$a_object, $a_method, $a_parameters="")
insertInstIntoIDs($a_inst, $a_res_ref_to_obj_id=true)
inserts installation id into ids (e.g.
afterUpdate()
After update.
setLanguage($a_val)
Set language.
newMobCopies($temp_dom)
Replaces media objects with copies.
getInitialOpenedContent()
Get initial opened content.
create()
create new page (with current xml data)
countPageContents()
Remove questions from document.
saveStyleUsage($a_domdoc, $a_old_nr=0)
Save all style class/template usages.
setActivationStart($a_activationstart)
Set Activation Start.
insertContentNode(&$a_cont_node, $a_pos, $a_mode=IL_INSERT_AFTER, $a_pcid="")
insert a content node before/after a sibling or as first child of a parent
deleteContentBeforeHierId($a_hid, $a_update=true)
delete content object with hierarchical id < $a_hid
increaseViewCnt()
Increase view cnt.
static _handleImportRepositoryLinks($a_rep_import_id, $a_rep_type, $a_rep_ref_id)
Change targest of repository links.
updateFromXML()
Updates page object with current xml content.
insertContent(&$a_cont_obj, $a_pos, $a_mode=IL_INSERT_AFTER, $a_pcid="")
insert a content node before/after a sibling or as first child of a parent
buildDom($a_force=false)
setRenderedTime($a_renderedtime)
Set Rendered Time.
getContainsQuestion()
Get contains question.
existsPCId($a_pc_id)
existsPCId
getActivationEnd()
Get Activation End.
deleteContentFromHierId($a_hid, $a_update=true)
delete content object with hierarchical id >= $a_hid
getXMLContent($a_incl_head=false)
get xml content of page
getLastUpdateOfIncludedElements()
Get last update of included elements (media objects and files).
afterConstructor()
After constructor.
static _lookupContainsDeactivatedElements($a_id, $a_parent_type, $a_lang="-")
lookup whether page contains deactivated elements
validateDom()
Validate the page content agains page DTD.
cutContents($a_hids)
Copy contents to clipboard and cut them from the page.
resolveFileItems($a_mapping)
Resolve file items (after import)
setLastChange($a_lastchange)
Set Last Change.
resolveMediaAliases($a_mapping, $a_reuse_existing_by_import=false)
Resolve media aliases (after import)
handleImportRepositoryLink($a_rep_import_id, $a_rep_type, $a_rep_ref_id)
static lookupParentId($a_id, $a_type)
Lookup parent id.
getHierIds()
get all hierarchical ids
resolveIntLinks($a_link_map=null)
Resolves all internal link targets of the page, if targets are available (after import)
appendLangVarXML(&$xml, $var)
containsIntLink()
returns true, if page was marked as containing an intern link (via setContainsIntLink) (this method s...
setShowActivationInfo($a_val)
Set show page activation info.
generatePcId($a_pc_ids=false)
Generate new pc id.
setRenderMd5($a_rendermd5)
Set Render MD5.
newQuestionCopies(&$temp_dom)
Replaces existing question content elements with new copies.
getActivationStart()
Get Activation Start.
getMultimediaXML()
get a xml string that contains all media object elements, that are referenced by any media alias in t...
getParentType()
Get parent type.
static _lookupActivationData($a_id, $a_parent_type, $a_lang="-")
Lookup activation data.
static lookupTranslations($a_parent_type, $a_id)
Lookup translations.
getContentObject($a_hier_id, $a_pc_id="")
Get a content object of the page.
saveInternalLinks($a_domdoc)
save internal links of page
handleRepositoryLinksOnCopy($a_mapping, $a_source_ref_id)
Handle repository links on copy process.
static getPagesWithLinks($a_parent_type, $a_parent_id, $a_lang="-")
Get all pages for parent object that contain internal links.
getPageContentsHashes()
Get page contents hashes.
getHistoryEntry($a_old_nr)
Get History Entry.
getContentTemplates()
Get content templates.
static _exists($a_parent_type, $a_id, $a_lang="", $a_no_cache=false)
Checks whether page exists.
static getAllPages($a_parent_type, $a_parent_id, $a_lang="-")
Get all pages for parent object.
setXMLContent($a_xml, $a_encoding="UTF-8")
set xml content of page, start with <PageObject...>, end with </PageObject>, comply with ILIAS DTD,...
setPageConfig($a_val)
Set page config object.
collectMediaObjects($a_inline_only=true)
get all media objects, that are referenced and used within the page
getAllFileObjIds()
Get all file object ids.
moveIntLinks($a_from_to)
Move internal links from one destination to another.
getFirstRowIds()
get ids of all first table rows
getMediaAliasElement($a_mob_id, $a_nr=1)
get complete media object (alias) element
getQuestionIds()
Get question ids.
checkPCIds()
Check, whether (all) page content hashes are set.
getDom()
Deprecated php4DomDocument.
getDomDoc()
Get dom doc (php5 dom document)
copy($a_id, $a_parent_type="", $a_parent_id=0, $a_clone_mobs=false)
Copy page.
copyXmlContent($a_clone_mobs=false)
Copy content of page; replace page components with copies where necessary (e.g.
getFO()
get fo page content
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)
copyPageToTranslation($a_target_lang)
Copy page to translation.
setActive($a_active)
set activation
addHierIDs()
Add hierarchical ID (e.g.
checkForTag($a_content_tag, $a_hier_id, $a_pc_id="")
Get content node from dom.
setId($a_id)
set id
insertPCIds()
Insert Page Content IDs.
containsDeactivatedElements($a_content)
Check whether content contains deactivated elements.
compareVersion($a_left, $a_right)
Compares to revisions of the page.
getAllPCIds()
Get all pc ids.
performAutomaticModifications()
Perform automatic modifications (may be overwritten by sub classes)
getFileItemIds()
get ids of all file items
getHistoryEntries()
Get History Entries.
static getParentObjectContributors($a_parent_type, $a_parent_id, $a_lang="-")
Get all contributors for parent object.
getLastChange()
Get Last Change.
lookforhier($a_hier_id)
getShowActivationInfo()
Get show page activation info.
resolveQuestionReferences($a_mapping)
Resolve all quesion references (after import)
bbCode2XML(&$a_content)
transforms bbCode to corresponding xml
& getContentNode($a_hier_id, $a_pc_id="")
Get content node from dom.
static getRecentChanges($a_parent_type, $a_parent_id, $a_period=30, $a_lang="")
Get recent pages changes for parent object.
handleCopiedContent($a_dom, $a_self_ass=true, $a_clone_mobs=false)
Handle copied content.
writeRenderedContent($a_content, $a_md5)
Write rendered content.
getLanguageVariablesXML()
Get language variables as XML.
needsImportParsing($a_parse="")
static preloadActivationDataByParentId($a_parent_id)
Preload activation data by Parent Id.
addChangeDivClasses($a_hashes)
getListItemIds()
get ids of all list items
static getLastChangeByParent($a_parent_type, $a_parent_id, $a_lang="")
Get all pages for parent object.
createFromXML()
Create new page object with current xml content.
newIIMCopies($temp_dom)
Replaces media objects in interactive images with copies of the interactive images.
__afterUpdate($a_domdoc, $a_xml, $a_creation=false, $a_empty=false)
After update event handler (internal).
static _writeActive($a_id, $a_parent_type, $a_active, $a_reset_scheduled_activation=true, $a_lang="-")
write activation status
getHierIdsForPCIds($a_pc_ids)
Get hier ids for a set of pc ids.
static _isScheduledActivation($a_id, $a_parent_type, $a_lang="-")
Check whether page is activated by time schedule.
copyContents($a_hids)
Copy contents to clipboard.
beforePageContentUpdate($a_page_content)
Before page content update.
update($a_validate=true, $a_no_history=false)
update complete page content in db (dom xml content is used)
static _writeParentId($a_parent_type, $a_pg_id, $a_par_id)
Write parent id.
getImportMode()
Get import mode.
appendXMLContent($a_xml)
append xml content to page setXMLContent must be called before and the same encoding must be used
deleteContents($a_hids, $a_update=true, $a_self_ass=false)
Delete multiple content objects.
getInternalLinks($a_cnt_multiple=false)
get all internal links that are used within the page
setContainsQuestion($a_val)
Set contains question.
moveContentAfter($a_source, $a_target, $a_spcid="", $a_tpcid="")
move content object from position $a_source before position $a_target (both hierarchical content ids)
getRenderedTime()
Get Rendered Time.
send_paragraph($par_id, $filename)
setLastChangeUser($a_val)
Set last change user.
resolveIIMMediaAliases($a_mapping)
Resolve iim media aliases (in ilContObjParse)
getActive($a_check_scheduled_activation=false)
get activation
setParagraphContent($a_hier_id, $a_content)
Set content of paragraph.
static _moveContentAfterHierId(&$a_source_page, &$a_target_page, $a_hid)
move content of hierarchical id >= $a_hid to other page
static _existsAndNotEmpty($a_parent_type, $a_id, $a_lang="-")
checks whether page exists and is not empty (may return true on some empty pages)
ILIAS Setting Class.
static shortenText($a_string, $a_start_pos, $a_num_bytes, $a_encoding='UTF-8')
Shorten text to the given number of bytes.
static getNamePresentation( $a_user_id, $a_user_image=false, $a_profile_link=false, $a_profile_back_link="", $a_force_first_lastname=false, $a_omit_login=false, $a_sortable=true, $a_return_data_array=false, $a_ctrl_path="ilpublicuserprofilegui")
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.
$template
$def
Definition: croninfo.php:21
$key
Definition: croninfo.php:18
$i
Definition: disco.tpl.php:19
$h
$links
$target_arr
Definition: goto.php:47
const ILIAS_VERSION_NUMERIC
xslt_free(&$proc)
xslt_create()
xpath_eval($xpath_context, $eval_str, $contextnode=null)
domxml_open_mem($str, $mode=0, &$error=null)
xpath_new_context($dom_document)
const DOMXML_LOAD_PARSING
$error
Definition: Error.php:17
if(function_exists( 'posix_getuid') &&posix_getuid()===0) if(!array_key_exists('t', $options)) $tag
Definition: cron.php:35
$time
Definition: cron.php:21
if($format !==null) $name
Definition: metadata.php:146
$end
Definition: saml1-acs.php:18
$errors
Definition: index.php:6
$ret
Definition: parser.php:6
$query
$type
$url
$s
Definition: pwgen.php:45
$handler
global $DIC
Definition: saml.php:7
foreach($_POST as $key=> $value) $res
$lm_set
$mobs
$a_content
Definition: workflow.php:93
$a_type
Definition: workflow.php:92
$params
Definition: disable.php:11
$text
Definition: errorreport.php:18
catch(Exception $e) if(isset( $_POST[ 'cancel'])) if(isset($_POST['continue'])) $cfg