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