ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
class.ilPageObject.php
Go to the documentation of this file.
1<?php
2
19define("IL_INSERT_BEFORE", 0);
20define("IL_INSERT_AFTER", 1);
21define("IL_INSERT_CHILD", 2);
22
23/*
24
25 - move dom related code to PageDom class/interface
26 - move ilDB dependency to ar object
27 - move internal links related code to extra class
28 - make factory available through DIC, opt allow decentralized factory parts
29 - PC types
30 -- internal links used/implemented?
31 -- styles used/implemented?
32 - application classes need
33 -- page object
34 --- page object should return php5 domdoc (getDom() vs getDomDoc()?)
35 esp. plugins should use this
36 -- remove content element hook, if content is not allowed
37 - PC types could move to components (e.g. blog, login)
38 - How to modularize xsl?
39 -- read from db?
40 -- xml entries say that xslt code is used -> read file and include in
41 main xslt file
42
43*/
44
46
52abstract class ilPageObject
53{
54 protected \ILIAS\COPage\Dom\DomUtil $dom_util;
55 protected \ILIAS\COPage\Link\LinkManager $link;
56 protected \ILIAS\COPage\PC\PCDefinition $pc_definition;
57 protected int $create_user = 0;
61 protected array $id_elements;
62 public int $old_nr;
63 protected bool $page_not_found = false;
64 protected bool $show_page_act_info = false;
66 public static array $exists = array();
67 protected ilDBInterface $db;
68 protected ilObjUser $user;
69 protected ilLanguage $lng;
70 protected ilTree $tree;
71 protected LOMServices $lom_services;
72 protected int $id;
73 public ?DOMDocument $dom = null;
74 public string $xml = "";
75 public string $encoding = "";
76 public DomNode $node;
77 public string $cur_dtd = "ilias_pg_9.dtd";
78 public bool $contains_int_link = false;
79 public bool $needs_parsing = false;
80 public string $parent_type = "";
81 public int $parent_id = 0;
82 public array $update_listeners = [];
83 public int $update_listener_cnt = 0;
84 public ?object $offline_handler = null; // see LMPresentation handleCodeParagraph
85 public bool $dom_builded = false;
86 public bool $history_saved = false;
87 protected string $language = "-";
88 protected static array $activation_data = array();
89 protected bool $import_mode = false;
90 protected ilLogger $log;
91 protected ?array $page_record = array();
92 protected bool $active = false;
94 protected string $rendermd5 = "";
95 protected string $renderedcontent = "";
96 protected string $renderedtime = "";
97 protected string $lastchange = "";
98 public int $last_change_user = 0;
99 protected bool $contains_question = false;
100 protected array $hier_ids = [];
101 protected ?string $activationstart = null; // IL_CAL_DATETIME format
102 protected ?string $activationend = null; // IL_CAL_DATETIME format
103 protected \ILIAS\COPage\ReadingTime\ReadingTimeManager $reading_time_manager;
104 protected $concrete_lang = "";
105 protected \ILIAS\COPage\ID\ContentIdManager $content_id_manager;
106 protected \ILIAS\COPage\Page\PageManager $page_manager;
107 protected \ILIAS\COPage\Style\StyleManager $style_manager;
108 protected \ILIAS\COPage\PC\DomainService $pc_service;
109
110 final public function __construct(
111 int $a_id = 0,
112 int $a_old_nr = 0,
113 string $a_lang = "-"
114 ) {
115 global $DIC;
116 $this->obj_definition = $DIC["objDefinition"];
117 $this->db = $DIC->database();
118 $this->user = $DIC->user();
119 $this->lng = $DIC->language();
120 $this->tree = $DIC->repositoryTree();
121 $this->log = ilLoggerFactory::getLogger('copg');
122 $this->lom_services = $DIC->learningObjectMetadata();
123
124 $this->reading_time_manager = new ILIAS\COPage\ReadingTime\ReadingTimeManager();
125
126 $this->parent_type = $this->getParentType();
127 $this->id = $a_id;
128 $this->setLanguage($a_lang);
129
130 $this->contains_int_link = false;
131 $this->needs_parsing = false;
132 $this->update_listeners = array();
133 $this->update_listener_cnt = 0;
134 $this->dom_builded = false;
135 $this->page_not_found = false;
136 $this->old_nr = $a_old_nr;
137 $this->encoding = "UTF-8";
138 $this->id_elements =
139 array("PageContent",
140 "TableRow",
141 "TableData",
142 "ListItem",
143 "FileItem",
144 "Section",
145 "Tab",
146 "ContentPopup",
147 "GridCell"
148 );
149 $this->setActive(true);
150 $this->show_page_act_info = false;
151
152 if ($a_id != 0) {
153 $this->read();
154 }
155
156 $this->initPageConfig();
157 $this->afterConstructor();
158 $domain = $DIC->copage()
159 ->internal()
160 ->domain();
161 $this->content_id_manager = $domain
162 ->contentIds($this);
163 $this->page_manager = $domain->page();
164 $this->pc_service = $domain->pc();
165 $this->pc_definition = $domain->pc()->definition();
166 $this->link = $domain->link();
167 $this->style_manager = $domain->style();
168 $this->dom_util = $domain->domUtil();
169 }
170
171 public function setContentIdManager(
172 \ILIAS\COPage\ID\ContentIdManager $content_id_manager
173 ): void {
174 $this->content_id_manager = $content_id_manager;
175 }
176
177 public function afterConstructor(): void
178 {
179 }
180
181 abstract public function getParentType(): string;
182
183 public function initPageConfig(): void
184 {
185 $cfg = ilPageObjectFactory::getConfigInstance($this->getParentType());
186 $this->setPageConfig($cfg);
187 }
188
193 public function setLanguage(string $a_val): void
194 {
195 $this->language = $a_val;
196 }
197
198 public function getLanguage(): string
199 {
200 return $this->language;
201 }
202
203 public function setPageConfig(ilPageConfig $a_val): void
204 {
205 $this->page_config = $a_val;
206 }
207
208 public function setConcreteLang(string $a_val)
209 {
210 $this->concrete_lang = $a_val;
211 }
212
213 public function getConcreteLang(): string
214 {
215 return $this->concrete_lang;
216 }
217
218 public function getPageConfig(): ilPageConfig
219 {
220 return $this->page_config;
221 }
222
223 public function setRenderMd5(string $a_rendermd5): void
224 {
225 $this->rendermd5 = $a_rendermd5;
226 }
227
228 public function getRenderMd5(): string
229 {
230 return $this->rendermd5;
231 }
232
233 public function setRenderedContent(string $a_renderedcontent): void
234 {
235 $this->renderedcontent = $a_renderedcontent;
236 }
237
238 public function getRenderedContent(): string
239 {
240 return $this->renderedcontent;
241 }
242
243 public function setRenderedTime(string $a_renderedtime): void
244 {
245 $this->renderedtime = $a_renderedtime;
246 }
247
248 public function getRenderedTime(): string
249 {
250 return $this->renderedtime;
251 }
252
253 public function setLastChange(string $a_lastchange): void
254 {
255 $this->lastchange = $a_lastchange;
256 }
257
258 public function getLastChange(): string
259 {
260 return $this->lastchange;
261 }
262
263 public function setLastChangeUser(int $a_val): void
264 {
265 $this->last_change_user = $a_val;
266 }
267
268 public function getLastChangeUser(): int
269 {
270 return $this->last_change_user;
271 }
272
273 public function setShowActivationInfo(bool $a_val): void
274 {
275 $this->show_page_act_info = $a_val;
276 }
277
278 public function getShowActivationInfo(): bool
279 {
280 return $this->show_page_act_info;
281 }
282
283 public function getCreationUserId(): int
284 {
285 return $this->create_user;
286 }
287
291 public function read(): void
292 {
293 $this->setActive(true);
294 if ($this->old_nr == 0) {
295 $query = "SELECT * FROM page_object" .
296 " WHERE page_id = " . $this->db->quote($this->id, "integer") .
297 " AND parent_type=" . $this->db->quote($this->getParentType(), "text") .
298 " AND lang = " . $this->db->quote($this->getLanguage(), "text");
299 $pg_set = $this->db->query($query);
300 if (!$this->page_record = $this->db->fetchAssoc($pg_set)) {
301 throw new ilCOPageNotFoundException("Error: Page " . $this->id . " is not in database" .
302 " (parent type " . $this->getParentType() . ", lang: " . $this->getLanguage() . ").");
303 }
304 $this->setActive($this->page_record["active"]);
305 $this->setActivationStart($this->page_record["activation_start"]);
306 $this->setActivationEnd($this->page_record["activation_end"]);
307 $this->setShowActivationInfo($this->page_record["show_activation_info"]);
308 } else {
309 $query = "SELECT * FROM page_history" .
310 " WHERE page_id = " . $this->db->quote($this->id, "integer") .
311 " AND parent_type=" . $this->db->quote($this->getParentType(), "text") .
312 " AND nr = " . $this->db->quote($this->old_nr, "integer") .
313 " AND lang = " . $this->db->quote($this->getLanguage(), "text");
314 $pg_set = $this->db->query($query);
315 $this->page_record = $this->db->fetchAssoc($pg_set);
316 }
317 if (!$this->page_record) {
318 throw new ilCOPageNotFoundException("Error: Page " . $this->id . " is not in database" .
319 " (parent type " . $this->getParentType() . ", lang: " . $this->getLanguage() . ").");
320 }
321 $this->xml = $this->page_record["content"];
322 $this->setParentId((int) $this->page_record["parent_id"]);
323 $this->last_change_user = (int) ($this->page_record["last_change_user"] ?? 0);
324 $this->create_user = (int) ($this->page_record["create_user"] ?? 0);
325 $this->setRenderedContent((string) ($this->page_record["rendered_content"] ?? ""));
326 $this->setRenderMd5((string) ($this->page_record["render_md5"] ?? ""));
327 $this->setRenderedTime((string) ($this->page_record["rendered_time"] ?? ""));
328 $this->setLastChange((string) ($this->page_record["last_change"] ?? ""));
329 }
330
335 public static function _exists(
336 string $a_parent_type,
337 int $a_id,
338 string $a_lang = "",
339 bool $a_no_cache = false
340 ): bool {
341 global $DIC;
342
343 $db = $DIC->database();
344
345 if (!$a_no_cache && isset(self::$exists[$a_parent_type . ":" . $a_id . ":" . $a_lang])) {
346 return self::$exists[$a_parent_type . ":" . $a_id . ":" . $a_lang];
347 }
348
349 $and_lang = "";
350 if ($a_lang != "") {
351 $and_lang = " AND lang = " . $db->quote($a_lang, "text");
352 }
353
354 $query = "SELECT page_id FROM page_object WHERE page_id = " . $db->quote($a_id, "integer") . " " .
355 "AND parent_type = " . $db->quote($a_parent_type, "text") . $and_lang;
356 $set = $db->query($query);
357 if ($row = $db->fetchAssoc($set)) {
358 self::$exists[$a_parent_type . ":" . $a_id . ":" . $a_lang] = true;
359 return true;
360 } else {
361 self::$exists[$a_parent_type . ":" . $a_id . ":" . $a_lang] = false;
362 return false;
363 }
364 }
365
369 public static function _existsAndNotEmpty(
370 string $a_parent_type,
371 int $a_id,
372 string $a_lang = "-"
373 ): bool {
374 return ilPageUtil::_existsAndNotEmpty($a_parent_type, $a_id, $a_lang);
375 }
376
380 public function buildDom(bool $a_force = false)
381 {
382 if ($this->dom_builded && !$a_force) {
383 return true;
384 }
385 $error = null;
386 if ($this->getXMLContent() === "") {
387 $this->setXMLContent("<PageObject></PageObject>");
388 }
389 $this->dom = $this->dom_util->docFromString($this->getXMLContent(true), $error);
390 $path = "//PageObject";
391 if (is_null($this->dom)) {
392 throw new ilCOPageException("Invalid page xml (" .
393 $this->getId() . "," . $this->getLanguage() . "): " . $this->getXMLContent(true));
394 }
395 $nodes = $this->dom_util->path($this->dom, $path);
396 if (count($nodes) == 1) {
397 $this->node = $nodes->item(0);
398 } else {
399 throw new ilCOPageException("Invalid page xml (" .
400 $this->getId() . "," . $this->getLanguage() . "): " . $this->getXMLContent(true));
401 }
402
403 if (empty($error)) {
404 $this->dom_builded = true;
405 return true;
406 } else {
407 return $error;
408 }
409 }
410
411 public function freeDom(): void
412 {
413 unset($this->dom);
414 }
415
419 public function getDomDoc(): DOMDocument
420 {
421 return $this->dom;
422 }
423
424 public function setId(int $a_id): void
425 {
426 $this->id = $a_id;
427 }
428
429 public function getId(): int
430 {
431 return $this->id;
432 }
433
434 public function setParentId(int $a_id): void
435 {
436 $this->parent_id = $a_id;
437 }
438
439 public function getParentId(): int
440 {
441 return $this->parent_id;
442 }
443
447 public function addUpdateListener(
448 object $a_object,
449 string $a_method,
450 $a_parameters = ""
451 ): void {
452 $cnt = $this->update_listener_cnt;
453 $this->update_listeners[$cnt]["object"] = $a_object;
454 $this->update_listeners[$cnt]["method"] = $a_method;
455 $this->update_listeners[$cnt]["parameters"] = $a_parameters;
456 $this->update_listener_cnt++;
457 }
458
459 public function callUpdateListeners(): void
460 {
461 for ($i = 0; $i < $this->update_listener_cnt; $i++) {
462 $object = $this->update_listeners[$i]["object"];
463 $method = $this->update_listeners[$i]["method"];
464 $parameters = $this->update_listeners[$i]["parameters"];
465 $object->$method($parameters);
466 }
467 }
468
469 public function setActive(bool $a_active): void
470 {
471 $this->active = $a_active;
472 }
473
474 public function getActive(
475 bool $a_check_scheduled_activation = false
476 ): bool {
477 if ($a_check_scheduled_activation && !$this->active) {
478 $start = new ilDateTime($this->getActivationStart(), IL_CAL_DATETIME);
479 $end = new ilDateTime($this->getActivationEnd(), IL_CAL_DATETIME);
480 $now = new ilDateTime(time(), IL_CAL_UNIX);
481 if (!ilDateTime::_before($now, $start) && !ilDateTime::_after($now, $end)) {
482 return true;
483 }
484 }
485 return $this->active;
486 }
487
491 public static function preloadActivationDataByParentId(int $a_parent_id): void
492 {
493 global $DIC;
494
495 $db = $DIC->database();
496 $set = $db->query(
497 "SELECT page_id, parent_type, lang, active, activation_start, activation_end, show_activation_info FROM page_object " .
498 " WHERE parent_id = " . $db->quote($a_parent_id, "integer")
499 );
500 while ($rec = $db->fetchAssoc($set)) {
501 self::$activation_data[$rec["page_id"] . ":" . $rec["parent_type"] . ":" . $rec["lang"]] = $rec;
502 }
503 }
504
508 public static function _lookupActive(
509 int $a_id,
510 string $a_parent_type,
511 bool $a_check_scheduled_activation = false,
512 string $a_lang = "-"
513 ): bool {
514 global $DIC;
515
516 $db = $DIC->database();
517
518 // language must be set at least to "-"
519 if ($a_lang == "") {
520 $a_lang = "-";
521 }
522
523 if (isset(self::$activation_data[$a_id . ":" . $a_parent_type . ":" . $a_lang])) {
524 $rec = self::$activation_data[$a_id . ":" . $a_parent_type . ":" . $a_lang];
525 } else {
526 $set = $db->queryF(
527 "SELECT active, activation_start, activation_end FROM page_object WHERE page_id = %s" .
528 " AND parent_type = %s AND lang = %s",
529 array("integer", "text", "text"),
530 array($a_id, $a_parent_type, $a_lang)
531 );
532 $rec = $db->fetchAssoc($set);
533 if (!$rec) {
534 return true;
535 }
536 }
537
538 $rec["n"] = ilUtil::now();
539 if (!$rec["active"] && $a_check_scheduled_activation) {
540 if ($rec["n"] >= $rec["activation_start"] &&
541 $rec["n"] <= $rec["activation_end"]) {
542 return true;
543 }
544 }
545
546 return (bool) $rec["active"];
547 }
548
552 public static function _isScheduledActivation(
553 int $a_id,
554 string $a_parent_type,
555 string $a_lang = "-"
556 ): bool {
557 global $DIC;
558
559 $db = $DIC->database();
560
561 // language must be set at least to "-"
562 if ($a_lang == "") {
563 $a_lang = "-";
564 }
565
566 //echo "<br>";
567 //var_dump(self::$activation_data); exit;
568 if (isset(self::$activation_data[$a_id . ":" . $a_parent_type . ":" . $a_lang])) {
569 $rec = self::$activation_data[$a_id . ":" . $a_parent_type . ":" . $a_lang];
570 } else {
571 $set = $db->queryF(
572 "SELECT active, activation_start, activation_end FROM page_object WHERE page_id = %s" .
573 " AND parent_type = %s AND lang = %s",
574 array("integer", "text", "text"),
575 array($a_id, $a_parent_type, $a_lang)
576 );
577 $rec = $db->fetchAssoc($set);
578 }
579
580 if (!$rec["active"] && $rec["activation_start"] != "") {
581 return true;
582 }
583
584 return false;
585 }
586
590 public static function _writeActive(
591 int $a_id,
592 string $a_parent_type,
593 bool $a_active
594 ): void {
595 global $DIC;
596
597 $db = $DIC->database();
598
599 // language must be set at least to "-"
600 $a_lang = "-";
601
602 $db->manipulateF(
603 "UPDATE page_object SET active = %s, activation_start = %s, " .
604 " activation_end = %s WHERE page_id = %s" .
605 " AND parent_type = %s AND lang = %s",
606 array("int", "timestamp", "timestamp", "integer", "text", "text"),
607 array((int) $a_active, null, null, $a_id, $a_parent_type, $a_lang)
608 );
609 }
610
614 public static function _lookupActivationData(
615 int $a_id,
616 string $a_parent_type,
617 string $a_lang = "-"
618 ): array {
619 global $DIC;
620
621 $db = $DIC->database();
622
623 // language must be set at least to "-"
624 if ($a_lang == "") {
625 $a_lang = "-";
626 }
627
628 if (isset(self::$activation_data[$a_id . ":" . $a_parent_type . ":" . $a_lang])) {
629 $rec = self::$activation_data[$a_id . ":" . $a_parent_type . ":" . $a_lang];
630 } else {
631 $set = $db->queryF(
632 "SELECT active, activation_start, activation_end, show_activation_info FROM page_object WHERE page_id = %s" .
633 " AND parent_type = %s AND lang = %s",
634 array("integer", "text", "text"),
635 array($a_id, $a_parent_type, $a_lang)
636 );
637 $rec = $db->fetchAssoc($set);
638 if (!$rec) {
639 return [
640 "active" => 1,
641 "activation_start" => null,
642 "activation_end" => null,
643 "show_activation_info" => 0
644 ];
645 }
646 }
647
648 return $rec;
649 }
650
651 public static function lookupParentId(int $a_id, string $a_type): int
652 {
653 global $DIC;
654
655 $db = $DIC->database();
656
657 $res = $db->query("SELECT parent_id FROM page_object WHERE page_id = " . $db->quote($a_id, "integer") . " " .
658 "AND parent_type=" . $db->quote($a_type, "text"));
659 $rec = $db->fetchAssoc($res);
660 return (int) ($rec["parent_id"] ?? 0);
661 }
662
663 public static function _writeParentId(string $a_parent_type, int $a_pg_id, int $a_par_id): void
664 {
665 global $DIC;
666
667 $db = $DIC->database();
668 $db->manipulateF(
669 "UPDATE page_object SET parent_id = %s WHERE page_id = %s" .
670 " AND parent_type = %s",
671 array("integer", "integer", "text"),
672 array($a_par_id, $a_pg_id, $a_parent_type)
673 );
674 }
675
679 public function setActivationStart(?string $a_activationstart): void
680 {
681 if ($a_activationstart == "") {
682 $a_activationstart = null;
683 }
684 $this->activationstart = $a_activationstart;
685 }
686
687 public function getActivationStart(): ?string
688 {
689 return $this->activationstart;
690 }
691
696 public function setActivationEnd(?string $a_activationend): void
697 {
698 if ($a_activationend == "") {
699 $a_activationend = null;
700 }
701 $this->activationend = $a_activationend;
702 }
703
704 public function getActivationEnd(): ?string
705 {
706 return $this->activationend;
707 }
708
712 public function getContentObject(
713 string $a_hier_id,
714 string $a_pc_id = ""
715 ): ?ilPageContent {
716 $node = $this->page_manager->content($this->getDomDoc())->getContentDomNode(
717 $a_hier_id,
718 $a_pc_id
719 );
720 $this->log->debug("getContentObject: " . " $a_hier_id, $a_pc_id, " . $node->nodeName);
721 return $this->pc_service->getByNode($node, $this);
722 }
723
727 public function getContentObjectForPcId(string $pcid): ?ilPageContent
728 {
729 $hier_ids = $this->getHierIdsForPCIds([$pcid]);
730 return $this->getContentObject($hier_ids[$pcid], $pcid);
731 }
732
736 public function getParentContentObjectForPcId(string $pcid): ?ilPageContent
737 {
738 $content_object = $this->getContentObjectForPcId($pcid);
739 $node = $content_object->getDomNode();
740 $node = $node->parentNode;
741 while ($node) {
742 if ($node->nodeName == "PageContent") {
743 $pcid = $node->getAttribute("PCID");
744 if ($pcid != "") {
745 return $this->getContentObjectForPcId($pcid);
746 }
747 }
748 $node = $node->parentNode;
749 }
750 return null;
751 }
752
753 public function getContentDomNode(string $a_hier_id, string $a_pc_id = ""): ?DOMNode
754 {
755 $cm = $this->page_manager->content($this->getDomDoc());
756 return $cm->getContentDomNode($a_hier_id, $a_pc_id);
757 }
758
759 public function getDomNodeForPCId(string $pc_id): ?DOMNode
760 {
761 return $this->getContentDomNode("", $pc_id);
762 }
763
770 public function setXMLContent(string $a_xml, string $a_encoding = "UTF-8"): void
771 {
772 $this->encoding = $a_encoding;
773 $this->xml = $a_xml;
774 }
775
780 public function appendXMLContent(string $a_xml): void
781 {
782 $this->xml .= $a_xml;
783 }
784
788 public function getXMLContent(bool $a_incl_head = false): string
789 {
790 // build full http path for XML DOCTYPE header.
791 // Under windows a relative path doesn't work :-(
792 if ($a_incl_head) {
793 //echo "+".$this->encoding."+";
794 $enc_str = (!empty($this->encoding))
795 ? "encoding=\"" . $this->encoding . "\""
796 : "";
797 return "<?xml version=\"1.0\" $enc_str ?>" .
798 "<!DOCTYPE PageObject SYSTEM \"" . $this->getIliasAbsolutePath() . "/components/ILIAS/Export/xml/" . $this->cur_dtd . "\">" .
799 $this->xml;
800 } else {
801 return $this->xml;
802 }
803 }
804
805 protected function getIliasAbsolutePath(): string
806 {
807 return ILIAS_ABSOLUTE_PATH;
808 }
809
815 public function copyXmlContent(
816 bool $a_clone_mobs = false,
817 int $a_new_parent_id = 0,
818 int $obj_copy_id = 0,
819 bool $self_ass = true
820 ): string {
821 $cm = $this->page_manager->contentFromXml($this->getXMLContent());
822 return $cm->copyXmlContent(
823 $this,
824 $a_clone_mobs,
825 $a_new_parent_id,
826 $obj_copy_id,
827 $self_ass
828 );
829 }
830
831 // @todo 1: begin: generalize, remove concrete dependencies
832
833
840 public function handleDeleteContent(?DOMNode $a_node = null, $move_operation = false): void
841 {
842 $pm = $this->page_manager->content($this->getDomDoc());
843 $pm->handleDeleteContent($this, $a_node, $move_operation);
844 }
845
850 public function getXMLFromDom(
851 bool $a_incl_head = false,
852 bool $a_append_mobs = false,
853 bool $a_append_bib = false,
854 string $a_append_str = "",
855 bool $a_omit_pageobject_tag = false,
856 int $style_id = 0,
857 bool $offline = false
858 ): string {
859 if ($a_incl_head) {
860 //echo "\n<br>#".$this->encoding."#";
861 return $this->dom_util->dump($this->node);
862 } else {
863 // append multimedia object elements
864 if ($a_append_mobs || $a_append_bib) {
865 $mobs = "";
866 $bibs = "";
867 if ($a_append_mobs) {
868 $mobs = $this->getMultimediaXML($offline);
869 }
870 if ($a_append_bib) {
871 // deprecated
872 // $bibs = $this->getBibliographyXML();
873 }
874 $trans = $this->getLanguageVariablesXML($style_id);
875 //echo htmlentities($this->dom->dump_node($this->node)); exit;
876 return "<dummy>" . $this->dom_util->dump($this->node) . $mobs . $bibs . $trans . $a_append_str . "</dummy>";
877 } else {
878 if (is_object($this->dom)) {
879 if ($a_omit_pageobject_tag) {
880 $xml = "";
881 foreach ($this->node->childNodes as $child) {
882 $xml .= $this->dom_util->dump($child);
883 }
884 } else {
885 $xml = $this->dom_util->dump($this->node);
886 $xml = preg_replace('/<\?xml[^>]*>/i', "", $xml);
887 $xml = preg_replace('/<!DOCTYPE[^>]*>/i', "", $xml);
888
889 // don't use dump_node. This gives always entities.
890 //return $this->dom->dump_node($this->node);
891 }
892 return $xml;
893 } else {
894 return "";
895 }
896 }
897 }
898 }
899
903 public function getLanguageVariablesXML(int $style_id = 0): string
904 {
905 $xml = "<LVs>";
906 $lang_vars = array(
907 "ed_paste_clip",
908 "ed_edit",
909 "ed_edit_prop",
910 "ed_delete",
911 "ed_moveafter",
912 "ed_movebefore",
913 "ed_go",
914 "ed_class",
915 "ed_width",
916 "ed_align_left",
917 "ed_align_right",
918 "ed_align_center",
919 "ed_align_left_float",
920 "ed_align_right_float",
921 "ed_delete_item",
922 "ed_new_item_before",
923 "ed_new_item_after",
924 "ed_copy_clip",
925 "please_select",
926 "ed_split_page",
927 "ed_item_up",
928 "ed_item_down",
929 "ed_split_page_next",
930 "ed_enable",
931 "de_activate",
932 "ed_paste",
933 "ed_edit_multiple",
934 "ed_cut",
935 "ed_copy",
936 "ed_insert_templ",
937 "ed_click_to_add_pg",
938 "download"
939 );
940
941 // collect lang vars from pc elements
942 $defs = $this->pc_definition->getPCDefinitions();
943 foreach ($defs as $def) {
944 $lang_vars[] = "pc_" . $def["pc_type"];
945 $lang_vars[] = "ed_insert_" . $def["pc_type"];
946
947 $cl = $def["pc_class"];
948 $lvs = call_user_func($def["pc_class"] . '::getLangVars');
949 foreach ($lvs as $lv) {
950 $lang_vars[] = $lv;
951 }
952 }
953
954 // workaround for #30561, should go to characteristic manager
955 $dummy_pc = new ilPCSectionGUI($this, null, "");
956 $dummy_pc->setStyleId($style_id);
957 foreach (["section", "table", "flist_li", "list_u", "list_o",
958 "table", "table_cell"] as $type) {
959 $dummy_pc->getCharacteristicsOfCurrentStyle([$type]);
960 foreach ($dummy_pc->getCharacteristics() as $char => $txt) {
961 $xml .= "<LV name=\"char_" . $type . "_" . $char . "\" value=\"" . $txt . "\"/>";
962 }
963 }
964 $type = "media_cont";
965 $dummy_pc = new ilPCMediaObjectGUI($this, null, "");
966 $dummy_pc->setStyleId($style_id);
967 $dummy_pc->getCharacteristicsOfCurrentStyle([$type]);
968 foreach ($dummy_pc->getCharacteristics() as $char => $txt) {
969 $xml .= "<LV name=\"char_" . $type . "_" . $char . "\" value=\"" . $txt . "\"/>";
970 }
971 foreach (["text_block", "heading1", "heading2", "heading3"] as $type) {
972 $dummy_pc = new ilPCParagraphGUI($this, null, "");
973 $dummy_pc->setStyleId($style_id);
974 $dummy_pc->getCharacteristicsOfCurrentStyle([$type]);
975 foreach ($dummy_pc->getCharacteristics() as $char => $txt) {
976 $xml .= "<LV name=\"char_" . $type . "_" . $char . "\" value=\"" . $txt . "\"/>";
977 }
978 }
979 foreach ($lang_vars as $lang_var) {
980 $xml .= $this->getLangVarXML($lang_var);
981 }
982 foreach ($this->pc_service->plugged()->getPluginLangVars() as $k => $v) {
983 $xml .= $this->getLangVarXMLForValue($k, $v);
984 }
985 $xml .= "</LVs>";
986 return $xml;
987 }
988
989 protected function getLangVarXML(string $var): string
990 {
991 return $this->getLangVarXMLForValue(
992 $var,
993 $this->lng->txt("cont_" . $var)
994 );
995 }
996
997 protected function getLangVarXMLForValue(string $var, string $val): string
998 {
999 $val = str_replace('"', "&quot;", $val);
1000 return "<LV name=\"$var\" value=\"" . $val . "\"/>";
1001 }
1002
1003 public function getFirstParagraphText(): string
1004 {
1005 return $this->pc_service->paragraph()->getFirstParagraphText($this);
1006 }
1007
1008 public function getParagraphForPCID(string $pcid): ?ilPCParagraph
1009 {
1010 return $this->pc_service->paragraph()->getParagraphForPCID($this, $pcid);
1011 }
1012
1013
1020 // @todo: can we do this better
1021 public function setContainsIntLink(bool $a_contains_link): void
1022 {
1023 $this->contains_int_link = $a_contains_link;
1024 }
1025
1030 // @todo: can we do this better
1031 public function containsIntLink(): bool
1032 {
1033 return $this->contains_int_link;
1034 }
1035
1036 public function setImportMode(bool $a_val): void
1037 {
1038 $this->import_mode = $a_val;
1039 }
1040
1041 public function getImportMode(): bool
1042 {
1043 return $this->import_mode;
1044 }
1045
1046 public function needsImportParsing(?bool $a_parse = null): bool
1047 {
1048 if ($a_parse === true) {
1049 $this->needs_parsing = true;
1050 }
1051 if ($a_parse === false) {
1052 $this->needs_parsing = false;
1053 }
1054 return $this->needs_parsing;
1055 }
1056
1057 // @todo: can we do this better
1058 public function setContainsQuestion(bool $a_val): void
1059 {
1060 $this->contains_question = $a_val;
1061 }
1062
1063 public function getContainsQuestion(): bool
1064 {
1065 return $this->contains_question;
1066 }
1067
1068
1073 public function collectMediaObjects(bool $a_inline_only = true): array
1074 {
1075 $mob_manager = $this->pc_service->mediaObject();
1076 return $mob_manager->collectMediaObjects($this->getDomDoc(), $a_inline_only);
1077 }
1078
1082 public function getInternalLinks(): array
1083 {
1084 return $this->link->getInternalLinks($this->getDomDoc());
1085 }
1086
1091 public function getMultimediaXML(
1092 bool $offline = false
1093 ): string {
1094 $mob_manager = $this->pc_service->mediaObject();
1095 return $mob_manager->getMultimediaXML($this->getDomDoc(), $offline);
1096 }
1097
1101 public function getMediaAliasElement(int $a_mob_id, int $a_nr = 1): string
1102 {
1103 $mob_manager = $this->pc_service->mediaObject();
1104 return $mob_manager->getMediaAliasElement(
1105 $this->getDomDoc(),
1106 $a_mob_id,
1107 $a_nr
1108 );
1109 }
1110
1114 public function validateDom(bool $throw = false): ?array
1115 {
1116 $this->stripHierIDs();
1117
1118 // possible fix for #14820
1119 //libxml_disable_entity_loader(false);
1120
1121 $error = null;
1122 $this->dom_util->validate($this->dom, $error, $throw);
1123 return $error;
1124 }
1125
1129 public function addHierIDs(): void
1130 {
1131 $this->content_id_manager->addHierIDsToDom();
1132 }
1133
1134 public function getHierIds(): array
1135 {
1136 return $this->content_id_manager->getHierIds();
1137 }
1138
1139 public function stripHierIDs(): void
1140 {
1141 $this->content_id_manager->stripHierIDsFromDom();
1142 }
1143
1144 public function stripPCIDs(): void
1145 {
1146 $this->content_id_manager->stripPCIDs();
1147 }
1148
1152 public function getHierIdsForPCIds(array $a_pc_ids): array
1153 {
1154 return $this->content_id_manager->getHierIdsForPCIds($a_pc_ids);
1155 }
1156
1157 public function getHierIdForPcId(string $pcid): string
1158 {
1159 return $this->content_id_manager->getHierIdForPcId($pcid);
1160 }
1161
1165 public function getPCIdsForHierIds(array $hier_ids): array
1166 {
1167 return $this->content_id_manager->getPCIdsForHierIds($hier_ids);
1168 }
1169
1170 public function getPCIdForHierId(string $hier_id): string
1171 {
1172 return $this->content_id_manager->getPCIdForHierId($hier_id);
1173 }
1174
1178 public function addFileSizes(): void
1179 {
1180 $this->pc_service->fileList()->addFileSizes($this->getDomDoc());
1181 }
1182
1187 public function resolveIntLinks(?array $a_link_map = null): bool
1188 {
1189 return $this->link->resolveIntLinks($this->getDomDoc(), $a_link_map);
1190 }
1191
1196 public function resolveMediaAliases(
1197 array $a_mapping,
1198 bool $a_reuse_existing_by_import = false
1199 ): bool {
1200 return $this->pc_service->mediaObject()->resolveMediaAliases(
1201 $this,
1202 $a_mapping,
1203 $a_reuse_existing_by_import
1204 );
1205 }
1206
1211 public function resolveIIMMediaAliases(array $a_mapping): bool
1212 {
1213 return $this->pc_service->interactiveImage()->resolveIIMMediaAliases(
1214 $this->getDomDoc(),
1215 $a_mapping
1216 );
1217 }
1218
1223 public function resolveFileItems(array $a_mapping): bool
1224 {
1225 return $this->pc_service->fileList()->resolveFileItems(
1226 $this->getDomDoc(),
1227 $a_mapping
1228 );
1229 }
1230
1235 public function resolveQuestionReferences(array $a_mapping): bool
1236 {
1237 $qm = $this->pc_service->question();
1238 return $qm->resolveQuestionReferences(
1239 $this->getDomDoc(),
1240 $a_mapping
1241 );
1242 }
1243
1244
1249 public function moveIntLinks(array $a_from_to): bool
1250 {
1251 $this->buildDom();
1252 $this->addHierIDs();
1253 return $this->link->moveIntLinks(
1254 $this->getDomDoc(),
1255 $a_from_to
1256 );
1257 }
1258
1259
1264 array $a_mapping,
1265 int $a_source_ref_id
1266 ): void {
1267 $this->buildDom();
1268
1269 $tree = $this->tree;
1270 $this->log->debug("Handle repository links...");
1271
1272 $defs = $this->pc_definition->getPCDefinitions();
1273 foreach ($defs as $def) {
1274 if (method_exists($def["pc_class"], 'afterRepositoryCopy')) {
1275 call_user_func($def["pc_class"] . '::afterRepositoryCopy', $this, $a_mapping, $a_source_ref_id);
1276 }
1277 }
1278
1279 $this->link->handleRepositoryLinksOnCopy($this->getDomDoc(), $a_mapping, $a_source_ref_id, $tree);
1280 }
1281
1282 public function setEmptyPageXml(): void
1283 {
1284 $this->setXMLContent("<PageObject></PageObject>");
1285 }
1286
1290 public function createFromXML(): void
1291 {
1292 $empty = false;
1293 if ($this->getXMLContent() === "") {
1294 $this->setEmptyPageXml();
1295 $empty = true;
1296 }
1297 $content = $this->getXMLContent();
1298 $this->buildDom(true);
1299 $dom_doc = $this->getDomDoc();
1300
1301 $errors = $this->validateDom(true);
1302
1303 $iel = $this->containsDeactivatedElements($content);
1304 $inl = $this->containsIntLinks($content);
1305 // create object
1306 $this->db->insert("page_object", array(
1307 "page_id" => array("integer", $this->getId()),
1308 "parent_id" => array("integer", $this->getParentId()),
1309 "lang" => array("text", $this->getLanguage()),
1310 "content" => array("clob", $content),
1311 "parent_type" => array("text", $this->getParentType()),
1312 "create_user" => array("integer", $this->user->getId()),
1313 "last_change_user" => array("integer", $this->user->getId()),
1314 "active" => array("integer", (int) $this->getActive()),
1315 "activation_start" => array("timestamp", $this->getActivationStart()),
1316 "activation_end" => array("timestamp", $this->getActivationEnd()),
1317 "show_activation_info" => array("integer", (int) $this->getShowActivationInfo()),
1318 "inactive_elements" => array("integer", $iel),
1319 "int_links" => array("integer", $inl),
1320 "created" => array("timestamp", ilUtil::now()),
1321 "last_change" => array("timestamp", ilUtil::now()),
1322 "is_empty" => array("integer", $empty)
1323 ));
1324 // after update event
1325 $this->__afterUpdate($dom_doc, $content, true, $empty);
1326 }
1327
1335 public function updateFromXML(): bool
1336 {
1337 $this->log->debug("ilPageObject, updateFromXML(): start, id: " . $this->getId());
1338
1339 $content = $this->getXMLContent();
1340
1341 $this->log->debug("ilPageObject, updateFromXML(): content: " . substr($content, 0, 100));
1342
1343 $this->buildDom(true);
1344 $dom_doc = $this->getDomDoc();
1345
1346 $errors = $this->validateDom(true);
1347
1348 $iel = $this->containsDeactivatedElements($content);
1349 $inl = $this->containsIntLinks($content);
1350
1351 $this->db->update("page_object", array(
1352 "content" => array("clob", $content),
1353 "parent_id" => array("integer", $this->getParentId()),
1354 "last_change_user" => array("integer", $this->user->getId()),
1355 "last_change" => array("timestamp", ilUtil::now()),
1356 "active" => array("integer", $this->getActive()),
1357 "activation_start" => array("timestamp", $this->getActivationStart()),
1358 "activation_end" => array("timestamp", $this->getActivationEnd()),
1359 "inactive_elements" => array("integer", $iel),
1360 "int_links" => array("integer", $inl),
1361 ), array(
1362 "page_id" => array("integer", $this->getId()),
1363 "parent_type" => array("text", $this->getParentType()),
1364 "lang" => array("text", $this->getLanguage())
1365 ));
1366
1367 // after update event
1368 $this->__afterUpdate($dom_doc, $content);
1369
1370 $this->log->debug("ilPageObject, updateFromXML(): end");
1371
1372 return true;
1373 }
1374
1379 final protected function __afterUpdate(
1380 DOMDocument $a_domdoc,
1381 string $a_xml,
1382 bool $a_creation = false,
1383 bool $a_empty = false
1384 ): void {
1385 // we do not need this if we are creating an empty page
1386 if (!$a_creation || !$a_empty) {
1387 // save internal link information
1388 // the page object is responsible to do this, since it "offers" the
1389 // internal link feature pc and page classes
1390 $this->saveInternalLinks($a_domdoc);
1391
1392 // save style usage
1393 $this->saveStyleUsage($a_domdoc);
1394
1395 // save estimated reading time
1396 $this->reading_time_manager->saveTime($this);
1397
1398 // pc classes hook
1399 $defs = $this->pc_definition->getPCDefinitions();
1400 foreach ($defs as $def) {
1401 $cl = $def["pc_class"];
1402 call_user_func($def["pc_class"] . '::afterPageUpdate', $this, $a_domdoc, $a_xml, $a_creation);
1403 }
1404 }
1405
1406 // call page hook
1407 $this->afterUpdate($a_domdoc, $a_xml);
1408
1409 // call update listeners
1410 $this->callUpdateListeners();
1411 }
1412
1416 public function afterUpdate(DOMDocument $domdoc, string $xml): void
1417 {
1418 }
1419
1426 public function update(bool $a_validate = true, bool $a_no_history = false)
1427 {
1428 $this->log->debug("start..., id: " . $this->getId());
1429 $lm_set = new ilSetting("lm");
1430
1431 // add missing pc ids
1432 if (!$this->checkPCIds()) {
1433 $this->insertPCIds();
1434 }
1435
1436 // test validating
1437 if ($a_validate) {
1438 $this->log->debug($this->dom_util->dump($this->getDomDoc()->documentElement));
1439 $errors = $this->validateDom();
1440 }
1441 //var_dump($errors); exit;
1442 if (empty($errors) && !$this->getEditLock()) {
1443 $lock = $this->getEditLockInfo();
1444 $errors[0] = array(0 => 0,
1445 1 => $this->lng->txt("cont_not_saved_edit_lock_expired") . "<br />" .
1446 $this->lng->txt("obj_usr") . ": " .
1447 ilUserUtil::getNamePresentation($lock["edit_lock_user"]) . "<br />" .
1448 $this->lng->txt("content_until") . ": " .
1449 ilDatePresentation::formatDate(new ilDateTime($lock["edit_lock_until"], IL_CAL_UNIX))
1450 );
1451 }
1452
1453 // check for duplicate pc ids
1454 $this->log->debug("checking duplicate ids");
1455 if ($this->hasDuplicatePCIds()) {
1456 $errors[0] = $this->lng->txt("cont_could_not_save_duplicate_pc_ids") .
1457 " (" . implode(", ", $this->getDuplicatePCIds()) . ")";
1458 }
1459
1460 if (!empty($errors)) {
1461 $this->log->debug("ilPageObject, update(): errors: " . print_r($errors, true));
1462 }
1463
1464 //echo "-".htmlentities($this->getXMLFromDom())."-"; exit;
1465 if (empty($errors)) {
1466 // @todo 1: is this page type or pc content type
1467 // related -> plugins should be able to hook in!?
1468
1469 $this->log->debug("perform automatic modifications");
1470 $this->performAutomaticModifications();
1471
1472 // get xml content
1473 $content = $this->getXMLFromDom();
1474 $dom_doc = $this->getDomDoc();
1475
1476 // this needs to be locked
1477
1478 // write history entry
1479 $old_set = $this->db->query("SELECT * FROM page_object WHERE " .
1480 "page_id = " . $this->db->quote($this->getId(), "integer") . " AND " .
1481 "parent_type = " . $this->db->quote($this->getParentType(), "text") . " AND " .
1482 "lang = " . $this->db->quote($this->getLanguage(), "text"));
1483 $last_nr_set = $this->db->query("SELECT max(nr) as mnr FROM page_history WHERE " .
1484 "page_id = " . $this->db->quote($this->getId(), "integer") . " AND " .
1485 "parent_type = " . $this->db->quote($this->getParentType(), "text") . " AND " .
1486 "lang = " . $this->db->quote($this->getLanguage(), "text"));
1487 $last_nr = $this->db->fetchAssoc($last_nr_set);
1488 if ($old_rec = $this->db->fetchAssoc($old_set)) {
1489 // only save, if something has changed
1490 // added user id to the check for ilias 5.0, 7.10.2014
1491 if (($content != $old_rec["content"] || $this->user->getId() != $old_rec["last_change_user"]) &&
1492 !$a_no_history && !$this->history_saved && $lm_set->get("page_history", 1)) {
1493 if ($old_rec["content"] != "<PageObject></PageObject>") {
1494 $this->db->manipulateF(
1495 "DELETE FROM page_history WHERE " .
1496 "page_id = %s AND parent_type = %s AND hdate = %s AND lang = %s",
1497 array("integer", "text", "timestamp", "text"),
1498 array($old_rec["page_id"],
1499 $old_rec["parent_type"],
1500 $old_rec["last_change"],
1501 $old_rec["lang"]
1502 )
1503 );
1504
1505 // the following lines are a workaround for
1506 // bug 6741
1507 $last_c = $old_rec["last_change"];
1508 if ($last_c == "") {
1509 $last_c = ilUtil::now();
1510 }
1511
1512 $this->db->insert("page_history", array(
1513 "page_id" => array("integer", $old_rec["page_id"]),
1514 "parent_type" => array("text", $old_rec["parent_type"]),
1515 "lang" => array("text", $old_rec["lang"]),
1516 "hdate" => array("timestamp", $last_c),
1517 "parent_id" => array("integer", $old_rec["parent_id"]),
1518 "content" => array("clob", $old_rec["content"]),
1519 "user_id" => array("integer", $old_rec["last_change_user"]),
1520 "ilias_version" => array("text", ILIAS_VERSION_NUMERIC),
1521 "nr" => array("integer", (int) $last_nr["mnr"] + 1)
1522 ));
1523
1524 $old_content = $old_rec["content"];
1525 $old_domdoc = new DOMDocument();
1526 $old_nr = $last_nr["mnr"] + 1;
1527 $old_domdoc->loadXML('<?xml version="1.0" encoding="UTF-8"?>' . $old_content);
1528
1529 // after history entry creation event
1530 $this->log->debug("calling __afterHistoryEntry");
1531 $this->__afterHistoryEntry($old_domdoc, $old_content, $old_nr);
1532
1533 // only save one time
1534 }
1535 $this->history_saved = true;
1536 }
1537 }
1538 //echo htmlentities($content);
1539 $em = (trim($content) == "<PageObject/>")
1540 ? 1
1541 : 0;
1542
1543 // @todo: pass dom instead?
1544 $this->log->debug("checking deactivated elements");
1545 $iel = $this->containsDeactivatedElements($content);
1546 $this->log->debug("checking internal links");
1547 $inl = $this->containsIntLinks($content);
1548
1549 $now = ilUtil::now();
1550 $this->lastchange = $now;
1551 $this->db->update("page_object", array(
1552 "content" => array("clob", $content),
1553 "parent_id" => array("integer", $this->getParentId()),
1554 "last_change_user" => array("integer", $this->user->getId()),
1555 "last_change" => array("timestamp", $now),
1556 "is_empty" => array("integer", $em),
1557 "active" => array("integer", $this->getActive()),
1558 "activation_start" => array("timestamp", $this->getActivationStart()),
1559 "activation_end" => array("timestamp", $this->getActivationEnd()),
1560 "show_activation_info" => array("integer", $this->getShowActivationInfo()),
1561 "inactive_elements" => array("integer", $iel),
1562 "int_links" => array("integer", $inl),
1563 ), array(
1564 "page_id" => array("integer", $this->getId()),
1565 "parent_type" => array("text", $this->getParentType()),
1566 "lang" => array("text", $this->getLanguage())
1567 ));
1568
1569 // after update event
1570 $this->log->debug("calling __afterUpdate()");
1571 $this->__afterUpdate($dom_doc, $content);
1572
1573 $this->log->debug(
1574 "...ending, updated and returning true, content: " . substr(
1575 $this->getXMLContent(),
1576 0,
1577 1000
1578 )
1579 );
1580
1581 //echo "<br>PageObject::update:".htmlentities($this->getXMLContent()).":";
1582 return true;
1583 } else {
1584 return $errors;
1585 }
1586 }
1587
1588 public function delete(): void
1589 {
1590 $copg_logger = ilLoggerFactory::getLogger('copg');
1591 $copg_logger->debug(
1592 "ilPageObject: Delete called for ID '" . $this->getId() . "'," .
1593 " parent type: '" . $this->getParentType() . "', " .
1594 " hist nr: '" . $this->old_nr . "', " .
1595 " lang: '" . $this->getLanguage() . "', "
1596 );
1597
1598 $mobs = array();
1599 if (!$this->page_not_found) {
1600 $this->buildDom();
1601 $mobs = $this->collectMediaObjects(false);
1602 }
1604 $this->getParentType() . ":pg",
1605 $this->getId(),
1606 false,
1607 $this->getLanguage()
1608 );
1609
1610 foreach ($mobs2 as $m) {
1611 if (!in_array($m, $mobs)) {
1612 $mobs[] = $m;
1613 }
1614 }
1615
1616 $copg_logger->debug("ilPageObject: ... found " . count($mobs) . " media objects.");
1617
1618 $this->__beforeDelete();
1619
1620 // treat plugged content
1621 $this->handleDeleteContent();
1622
1623 // delete style usages
1624 $this->deleteStyleUsages(false);
1625
1626 // delete internal links
1627 $this->deleteInternalLinks();
1628
1629 // delete all mob usages
1630 ilObjMediaObject::_deleteAllUsages($this->getParentType() . ":pg", $this->getId());
1631
1632 // delete news
1633 if (!$this->isTranslationPage()) {
1635 $this->getParentId(),
1636 $this->getParentType(),
1637 $this->getId(),
1638 "pg"
1639 );
1640 }
1641
1642 // delete page_object entry
1643 $and = $this->isTranslationPage()
1644 ? " AND lang = " . $this->db->quote($this->getLanguage(), "text")
1645 : "";
1646 $this->db->manipulate("DELETE FROM page_object " .
1647 "WHERE page_id = " . $this->db->quote($this->getId(), "integer") .
1648 " AND parent_type= " . $this->db->quote($this->getParentType(), "text") . $and);
1649
1650 // delete media objects
1651 foreach ($mobs as $mob_id) {
1652 $copg_logger->debug("ilPageObject: ... processing mob " . $mob_id . ".");
1653
1654 if (ilObject::_lookupType($mob_id) != 'mob') {
1655 $copg_logger->debug("ilPageObject: ... type mismatch. Ignoring mob " . $mob_id . ".");
1656 continue;
1657 }
1658
1659 if (ilObject::_exists($mob_id)) {
1660 $copg_logger->debug("ilPageObject: ... delete mob " . $mob_id . ".");
1661
1662 $mob_obj = new ilObjMediaObject($mob_id);
1663 $mob_obj->delete();
1664 } else {
1665 $copg_logger->debug("ilPageObject: ... missing mob " . $mob_id . ".");
1666 }
1667 }
1668
1669 $this->__afterDelete();
1670 }
1671
1672 protected function isTranslationPage(): bool
1673 {
1674 return !in_array($this->getLanguage(), ["", "-"]);
1675 }
1676
1680 final protected function __beforeDelete(): void
1681 {
1682 // pc classes hook
1683 $defs = $this->pc_definition->getPCDefinitions();
1684 foreach ($defs as $def) {
1685 $cl = $def["pc_class"];
1686 call_user_func($def["pc_class"] . '::beforePageDelete', $this);
1687 }
1688 }
1689
1690 final protected function __afterDelete(): void
1691 {
1692 $this->afterDelete();
1693 }
1694
1695 protected function afterDelete(): void
1696 {
1697 }
1698
1699 final protected function __afterHistoryEntry(
1700 DOMDocument $a_old_domdoc,
1701 string $a_old_content,
1702 int $a_old_nr
1703 ): void {
1704 // save style usage
1705 $this->saveStyleUsage($a_old_domdoc, $a_old_nr);
1706
1707 // pc classes hook
1708 $defs = $this->pc_definition->getPCDefinitions();
1709 foreach ($defs as $def) {
1710 $cl = $def["pc_class"];
1711 call_user_func(
1712 $def["pc_class"] . '::afterPageHistoryEntry',
1713 $this,
1714 $a_old_domdoc,
1715 $a_old_content,
1716 $a_old_nr
1717 );
1718 }
1719 }
1720
1724 public function saveStyleUsage(
1725 DOMDocument $a_domdoc,
1726 int $a_old_nr = 0
1727 ): void {
1728 $this->style_manager->saveStyleUsage(
1729 $this,
1730 $a_domdoc,
1731 $a_old_nr
1732 );
1733 }
1734
1738 public function deleteStyleUsages(int $a_old_nr = 0): void
1739 {
1740 $this->style_manager->deleteStyleUsages($this, $a_old_nr);
1741 }
1742
1748 public function getLastUpdateOfIncludedElements(): string
1749 {
1751 $this->getParentType() . ":pg",
1752 $this->getId()
1753 );
1754 $files = ilObjFile::_getFilesOfObject(
1755 $this->getParentType() . ":pg",
1756 $this->getId()
1757 );
1758 $objs = array_merge($mobs, $files);
1760 }
1761
1765 public function deleteInternalLinks(): void
1766 {
1767 $this->link->deleteInternalLinks($this);
1768 }
1769
1770
1775 public function saveInternalLinks(DOMDocument $a_domdoc): void
1776 {
1777 $this->link->saveInternalLinks(
1778 $this,
1779 $a_domdoc
1780 );
1781 }
1782
1786 public function create(bool $a_import = false): void
1787 {
1788 $this->createFromXML();
1789 }
1790
1797 public function deleteContent(
1798 string $a_hid,
1799 bool $a_update = true,
1800 string $a_pcid = "",
1801 bool $move_operation = false
1802 ) {
1803 $pm = $this->page_manager->content($this->getDomDoc());
1804 $pm->deleteContent($this, $a_hid, $a_pcid, $move_operation);
1805 if ($a_update) {
1806 return $this->update();
1807 }
1808 return true;
1809 }
1810
1818 public function deleteContents(
1819 array $a_hids,
1820 bool $a_update = true,
1821 bool $a_self_ass = false,
1822 bool $move_operation = false
1823 ) {
1824 $pm = $this->page_manager->content($this->getDomDoc());
1825 $pm->deleteContents($this, $a_hids, $a_self_ass, $move_operation);
1826 if ($a_update) {
1827 return $this->update();
1828 }
1829 return true;
1830 }
1831
1837 public function cutContents(array $a_hids)
1838 {
1839 $this->copyContents($a_hids);
1840 return $this->deleteContents(
1841 $a_hids,
1842 true,
1843 $this->getPageConfig()->getEnableSelfAssessment(),
1844 true
1845 );
1846 }
1847
1851 public function copyContents(array $a_hids): void
1852 {
1853 $cm = $this->page_manager->content($this->getDomDoc());
1854 $cm->copyContents($a_hids, $this->user);
1855 }
1856
1862 public function pasteContents(
1863 string $a_hier_id,
1864 bool $a_self_ass = false
1865 ) {
1866 $user = $this->user;
1867 $cm = $this->page_manager->content($this->getDomDoc());
1868 $cm->pasteContents(
1869 $user,
1870 $a_hier_id,
1871 $this,
1872 $a_self_ass
1873 );
1874 return $this->update();
1875 }
1876
1884 public function switchEnableMultiple(
1885 array $a_hids,
1886 bool $a_update = true,
1887 bool $a_self_ass = false
1888 ) {
1889 $cm = $this->page_manager->content($this->getDomDoc());
1890 $cm->switchEnableMultiple($this, $a_hids, $a_self_ass);
1891 if ($a_update) {
1892 return $this->update();
1893 }
1894 return true;
1895 }
1896
1900 public function insertContent(
1901 ilPageContent $a_cont_obj,
1902 string $a_pos,
1903 int $a_mode = IL_INSERT_AFTER,
1904 string $a_pcid = "",
1905 bool $remove_placeholder = true
1906 ): void {
1907 $cm = $this->page_manager->content($this->getDomDoc());
1908 $cm->insertContent(
1909 $a_cont_obj,
1910 $a_pos,
1911 $a_mode,
1912 $a_pcid,
1913 $remove_placeholder,
1914 $this->getPageConfig()->getEnablePCType("PlaceHolder")
1915 );
1916 }
1917
1921 public function insertContentNode(
1922 DOMNode $a_cont_node,
1923 string $a_pos,
1924 int $a_mode = IL_INSERT_AFTER,
1925 string $a_pcid = ""
1926 ): void {
1927 $cm = $this->page_manager->content($this->getDomDoc());
1928 $cm->insertContentNode(
1929 $a_cont_node,
1930 $a_pos,
1931 $a_mode,
1932 $a_pcid
1933 );
1934 }
1935
1936
1949 public function moveContentAfter(
1950 string $a_source,
1951 string $a_target,
1952 string $a_spcid = "",
1953 string $a_tpcid = ""
1954 ) {
1955 $cm = $this->page_manager->content($this->getDomDoc());
1956 $cm->moveContentAfter(
1957 $this,
1958 $a_source,
1959 $a_target,
1960 $a_spcid,
1961 $a_tpcid
1962 );
1963 return $this->update();
1964 }
1965
1972 public function insertInstIntoIDs(
1973 string $a_inst,
1974 bool $a_res_ref_to_obj_id = true
1975 ): void {
1976 $cm = $this->page_manager->content($this->getDomDoc());
1977 $cm->insertInstIntoIDs($a_inst, $a_res_ref_to_obj_id);
1978 }
1979
1983 public function checkPCIds(): bool
1984 {
1985 return $this->content_id_manager->checkPCIds();
1986 }
1987
1991 public function getAllPCIds(): array
1992 {
1993 return $this->content_id_manager->getAllPCIds();
1994 }
1995
1996 public function hasDuplicatePCIds(): bool
1997 {
1998 return $this->content_id_manager->hasDuplicatePCIds();
1999 }
2000
2005 public function getDuplicatePCIds(): array
2006 {
2007 return $this->content_id_manager->getDuplicatePCIds();
2008 }
2009
2010 public function generatePCId(): string
2011 {
2012 return $this->content_id_manager->generatePCId();
2013 }
2014
2018 public function insertPCIds(): void
2019 {
2020 $this->content_id_manager->insertPCIds();
2021 }
2022
2023 public function sendParagraph(
2024 string $par_id,
2025 string $filename
2026 ): void {
2027 $this->pc_service->paragraph()->send(
2028 $this->getDomDoc(),
2029 $par_id,
2030 $filename
2031 );
2032 }
2033
2034 public function registerOfflineHandler(object $handler): void
2035 {
2036 $this->offline_handler = $handler;
2037 }
2038
2039 public function getOfflineHandler(): ?object
2040 {
2041 return $this->offline_handler;
2042 }
2043
2048 int $a_id,
2049 string $a_parent_type,
2050 string $a_lang = "-"
2051 ): bool {
2052 global $DIC;
2053
2054 $db = $DIC->database();
2055
2056 if ($a_lang == "") {
2057 $a_lang = "-";
2058 }
2059
2060 $query = "SELECT * FROM page_object WHERE page_id = " .
2061 $db->quote($a_id, "integer") . " AND " .
2062 " parent_type = " . $db->quote($a_parent_type, "text") . " AND " .
2063 " lang = " . $db->quote($a_lang, "text") . " AND " .
2064 " inactive_elements = " . $db->quote(1, "integer");
2065 $obj_set = $db->query($query);
2066
2067 if ($obj_rec = $obj_set->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) {
2068 return true;
2069 }
2070
2071 return false;
2072 }
2073
2077 public function containsDeactivatedElements(string $a_content): bool
2078 {
2079 if (strpos($a_content, " Enabled=\"False\"")) {
2080 return true;
2081 }
2082 return false;
2083 }
2084
2088 public function getHistoryEntries(): array
2089 {
2090 $db = $this->db;
2091
2092 $h_query = "SELECT * FROM page_history " .
2093 " WHERE page_id = " . $db->quote($this->getId(), "integer") .
2094 " AND parent_type = " . $db->quote($this->getParentType(), "text") .
2095 " AND lang = " . $db->quote($this->getLanguage(), "text") .
2096 " ORDER BY hdate DESC";
2097
2098 $hset = $db->query($h_query);
2099 $hentries = array();
2100
2101 while ($hrec = $db->fetchAssoc($hset)) {
2102 $hrec["sortkey"] = (int) $hrec["nr"];
2103 $hrec["user"] = (int) $hrec["user_id"];
2104 $hentries[] = $hrec;
2105 }
2106 //var_dump($hentries);
2107 return $hentries;
2108 }
2109
2113 public function getHistoryEntry(int $a_old_nr): ?array
2114 {
2115 $db = $this->db;
2116
2117 $res = $db->queryF(
2118 "SELECT * FROM page_history " .
2119 " WHERE page_id = %s " .
2120 " AND parent_type = %s " .
2121 " AND nr = %s" .
2122 " AND lang = %s",
2123 array("integer", "text", "integer", "text"),
2124 array($this->getId(), $this->getParentType(), $a_old_nr, $this->getLanguage())
2125 );
2126 if ($hrec = $db->fetchAssoc($res)) {
2127 return $hrec;
2128 }
2129
2130 return null;
2131 }
2132
2138 public function getHistoryInfo(int $a_nr): array
2139 {
2140 $db = $this->db;
2141
2142 // determine previous entry
2143 $and_nr = ($a_nr > 0)
2144 ? " AND nr < " . $db->quote($a_nr, "integer")
2145 : "";
2146 $res = $db->query("SELECT MAX(nr) mnr FROM page_history " .
2147 " WHERE page_id = " . $db->quote($this->getId(), "integer") .
2148 " AND parent_type = " . $db->quote($this->getParentType(), "text") .
2149 " AND lang = " . $db->quote($this->getLanguage(), "text") .
2150 $and_nr);
2151 $row = $db->fetchAssoc($res);
2152 if ($row["mnr"] > 0) {
2153 $res = $db->query("SELECT * FROM page_history " .
2154 " WHERE page_id = " . $db->quote($this->getId(), "integer") .
2155 " AND parent_type = " . $db->quote($this->getParentType(), "text") .
2156 " AND lang = " . $db->quote($this->getLanguage(), "text") .
2157 " AND nr = " . $db->quote((int) $row["mnr"], "integer"));
2158 $row = $db->fetchAssoc($res);
2159 $ret["previous"] = $row;
2160 }
2161
2162 // determine next entry
2163 $res = $db->query("SELECT MIN(nr) mnr FROM page_history " .
2164 " WHERE page_id = " . $db->quote($this->getId(), "integer") .
2165 " AND parent_type = " . $db->quote($this->getParentType(), "text") .
2166 " AND lang = " . $db->quote($this->getLanguage(), "text") .
2167 " AND nr > " . $db->quote($a_nr, "integer"));
2168 $row = $db->fetchAssoc($res);
2169 if ($row["mnr"] > 0) {
2170 $res = $db->query("SELECT * FROM page_history " .
2171 " WHERE page_id = " . $db->quote($this->getId(), "integer") .
2172 " AND parent_type = " . $db->quote($this->getParentType(), "text") .
2173 " AND lang = " . $db->quote($this->getLanguage(), "text") .
2174 " AND nr = " . $db->quote((int) $row["mnr"], "integer"));
2175 $row = $db->fetchAssoc($res);
2176 $ret["next"] = $row;
2177 }
2178
2179 // current
2180 if ($a_nr > 0) {
2181 $res = $db->query("SELECT * FROM page_history " .
2182 " WHERE page_id = " . $db->quote($this->getId(), "integer") .
2183 " AND parent_type = " . $db->quote($this->getParentType(), "text") .
2184 " AND lang = " . $db->quote($this->getLanguage(), "text") .
2185 " AND nr = " . $db->quote($a_nr, "integer"));
2186 } else {
2187 $res = $db->query("SELECT page_id, last_change hdate, parent_type, parent_id, last_change_user user_id, content, lang FROM page_object " .
2188 " WHERE page_id = " . $db->quote($this->getId(), "integer") .
2189 " AND parent_type = " . $db->quote($this->getParentType(), "text") .
2190 " AND lang = " . $db->quote($this->getLanguage(), "text"));
2191 }
2192 $row = $db->fetchAssoc($res);
2193 $ret["current"] = $row;
2194
2195 return $ret;
2196 }
2197
2198 public function preparePageForCompare(ilPageObject $page): void
2199 {
2200 }
2201
2205 public function increaseViewCnt(): void
2206 {
2207 $db = $this->db;
2208
2209 $db->manipulate("UPDATE page_object " .
2210 " SET view_cnt = view_cnt + 1 " .
2211 " WHERE page_id = " . $db->quote($this->getId(), "integer") .
2212 " AND parent_type = " . $db->quote($this->getParentType(), "text") .
2213 " AND lang = " . $db->quote($this->getLanguage(), "text"));
2214 }
2215
2222 public static function getRecentChanges(
2223 string $a_parent_type,
2224 int $a_parent_id,
2225 int $a_period = 30,
2226 string $a_lang = ""
2227 ): array {
2228 global $DIC;
2229
2230 $db = $DIC->database();
2231
2232 $and_lang = "";
2233 if ($a_lang != "") {
2234 $and_lang = " AND lang = " . $db->quote($a_lang, "text");
2235 }
2236
2237 $page_changes = array();
2238 $limit_ts = date('Y-m-d H:i:s', time() - ($a_period * 24 * 60 * 60));
2239 $q = "SELECT * FROM page_object " .
2240 " WHERE parent_id = " . $db->quote($a_parent_id, "integer") .
2241 " AND parent_type = " . $db->quote($a_parent_type, "text") .
2242 " AND last_change >= " . $db->quote($limit_ts, "timestamp") . $and_lang;
2243 // " AND (TO_DAYS(now()) - TO_DAYS(last_change)) <= ".((int)$a_period);
2244 $set = $db->query($q);
2245 while ($page = $db->fetchAssoc($set)) {
2246 $page_changes[] = array(
2247 "date" => $page["last_change"],
2248 "id" => $page["page_id"],
2249 "lang" => $page["lang"],
2250 "type" => "page",
2251 "user" => $page["last_change_user"]
2252 );
2253 }
2254
2255 $and_str = "";
2256 if ($a_period > 0) {
2257 $limit_ts = date('Y-m-d H:i:s', time() - ($a_period * 24 * 60 * 60));
2258 $and_str = " AND hdate >= " . $db->quote($limit_ts, "timestamp") . " ";
2259 }
2260
2261 $q = "SELECT * FROM page_history " .
2262 " WHERE parent_id = " . $db->quote($a_parent_id, "integer") .
2263 " AND parent_type = " . $db->quote($a_parent_type, "text") .
2264 $and_str . $and_lang;
2265 $set = $db->query($q);
2266 while ($page = $db->fetchAssoc($set)) {
2267 $page_changes[] = array(
2268 "date" => $page["hdate"],
2269 "id" => $page["page_id"],
2270 "lang" => $page["lang"],
2271 "type" => "hist",
2272 "nr" => $page["nr"],
2273 "user" => $page["user_id"]
2274 );
2275 }
2276
2277 $page_changes = ilArrayUtil::sortArray($page_changes, "date", "desc");
2278
2279 return $page_changes;
2280 }
2281
2285 public static function getAllPages(
2286 string $a_parent_type,
2287 int $a_parent_id,
2288 string $a_lang = "-"
2289 ): array {
2290 global $DIC;
2291
2292 $db = $DIC->database();
2293
2294 $and_lang = "";
2295 if ($a_lang != "") {
2296 $and_lang = " AND lang = " . $db->quote($a_lang, "text");
2297 }
2298
2299 $q = "SELECT * FROM page_object " .
2300 " WHERE parent_id = " . $db->quote($a_parent_id, "integer") .
2301 " AND parent_type = " . $db->quote($a_parent_type, "text") . $and_lang;
2302 $set = $db->query($q);
2303 $pages = array();
2304 while ($page = $db->fetchAssoc($set)) {
2305 $key_add = ($a_lang == "")
2306 ? ":" . $page["lang"]
2307 : "";
2308 $pages[$page["page_id"] . $key_add] = array(
2309 "date" => $page["last_change"],
2310 "id" => $page["page_id"],
2311 "lang" => $page["lang"],
2312 "user" => $page["last_change_user"]
2313 );
2314 }
2315
2316 return $pages;
2317 }
2318
2322 public static function getNewPages(
2323 string $a_parent_type,
2324 int $a_parent_id,
2325 string $a_lang = "-"
2326 ): array {
2327 global $DIC;
2328
2329 $db = $DIC->database();
2330
2331 $and_lang = "";
2332 if ($a_lang != "") {
2333 $and_lang = " AND lang = " . $db->quote($a_lang, "text");
2334 }
2335
2336 $pages = array();
2337
2338 $q = "SELECT * FROM page_object " .
2339 " WHERE parent_id = " . $db->quote($a_parent_id, "integer") .
2340 " AND parent_type = " . $db->quote($a_parent_type, "text") . $and_lang .
2341 " ORDER BY created DESC";
2342 $set = $db->query($q);
2343 while ($page = $db->fetchAssoc($set)) {
2344 if ($page["created"] != "") {
2345 $pages[] = array(
2346 "created" => $page["created"],
2347 "id" => $page["page_id"],
2348 "lang" => $page["lang"],
2349 "user" => $page["create_user"],
2350 );
2351 }
2352 }
2353
2354 return $pages;
2355 }
2356
2362 public static function getParentObjectContributors(
2363 string $a_parent_type,
2364 int $a_parent_id,
2365 string $a_lang = "-"
2366 ): array {
2367 global $DIC;
2368
2369 $db = $DIC->database();
2370
2371 $and_lang = "";
2372 if ($a_lang != "") {
2373 $and_lang = " AND lang = " . $db->quote($a_lang, "text");
2374 }
2375
2376 $contributors = array();
2377 $set = $db->queryF(
2378 "SELECT last_change_user, lang, page_id FROM page_object " .
2379 " WHERE parent_id = %s AND parent_type = %s " .
2380 " AND last_change_user != %s" . $and_lang,
2381 array("integer", "text", "integer"),
2382 array($a_parent_id, $a_parent_type, 0)
2383 );
2384
2385 while ($page = $db->fetchAssoc($set)) {
2386 if ($a_lang == "") {
2387 $contributors[$page["last_change_user"]][$page["page_id"]][$page["lang"]] = 1;
2388 } else {
2389 $contributors[$page["last_change_user"]][$page["page_id"]] = 1;
2390 }
2391 }
2392
2393 $set = $db->queryF(
2394 "SELECT count(*) as cnt, lang, page_id, user_id FROM page_history " .
2395 " WHERE parent_id = %s AND parent_type = %s AND user_id != %s " . $and_lang .
2396 " GROUP BY page_id, user_id, lang ",
2397 array("integer", "text", "integer"),
2398 array($a_parent_id, $a_parent_type, 0)
2399 );
2400 while ($hpage = $db->fetchAssoc($set)) {
2401 if ($a_lang == "") {
2402 $contributors[$hpage["user_id"]][$hpage["page_id"]][$hpage["lang"]] =
2403 ($contributors[$hpage["user_id"]][$hpage["page_id"]][$hpage["lang"]] ?? 0) + $hpage["cnt"];
2404 } else {
2405 $contributors[$hpage["user_id"]][$hpage["page_id"]] =
2406 ($contributors[$hpage["user_id"]][$hpage["page_id"]] ?? 0) + $hpage["cnt"];
2407 }
2408 }
2409
2410 $c = array();
2411 foreach ($contributors as $k => $co) {
2412 if (ilObject::_lookupType($k) == "usr") {
2413 $name = ilObjUser::_lookupName($k);
2414 $c[] = array("user_id" => $k,
2415 "pages" => $co,
2416 "lastname" => $name["lastname"],
2417 "firstname" => $name["firstname"]
2418 );
2419 }
2420 }
2421
2422 return $c;
2423 }
2424
2428 public static function getPageContributors(
2429 string $a_parent_type,
2430 int $a_page_id,
2431 string $a_lang = "-"
2432 ): array {
2433 global $DIC;
2434
2435 $db = $DIC->database();
2436
2437 $and_lang = "";
2438 if ($a_lang != "") {
2439 $and_lang = " AND lang = " . $db->quote($a_lang, "text");
2440 }
2441
2442 $contributors = array();
2443 $set = $db->queryF(
2444 "SELECT last_change_user, lang FROM page_object " .
2445 " WHERE page_id = %s AND parent_type = %s " .
2446 " AND last_change_user != %s" . $and_lang,
2447 array("integer", "text", "integer"),
2448 array($a_page_id, $a_parent_type, 0)
2449 );
2450
2451 while ($page = $db->fetchAssoc($set)) {
2452 if ($a_lang == "") {
2453 $contributors[$page["last_change_user"]][$page["lang"]] = 1;
2454 } else {
2455 $contributors[$page["last_change_user"]] = 1;
2456 }
2457 }
2458
2459 $set = $db->queryF(
2460 "SELECT count(*) as cnt, lang, page_id, user_id FROM page_history " .
2461 " WHERE page_id = %s AND parent_type = %s AND user_id != %s " . $and_lang .
2462 " GROUP BY user_id, page_id, lang ",
2463 array("integer", "text", "integer"),
2464 array($a_page_id, $a_parent_type, 0)
2465 );
2466 while ($hpage = $db->fetchAssoc($set)) {
2467 if ($a_lang === "") {
2468 $contributors[$hpage["user_id"]][$page["lang"]] =
2469 ($contributors[$hpage["user_id"]][$page["lang"]] ?? 0) + $hpage["cnt"];
2470 } else {
2471 $contributors[$hpage["user_id"]] =
2472 ($contributors[$hpage["user_id"]] ?? 0) + $hpage["cnt"];
2473 }
2474 }
2475
2476 $c = array();
2477 foreach ($contributors as $k => $co) {
2478 $name = ilObjUser::_lookupName($k);
2479 $c[] = array("user_id" => $k,
2480 "pages" => $co,
2481 "lastname" => $name["lastname"],
2482 "firstname" => $name["firstname"]
2483 );
2484 }
2485
2486 return $c;
2487 }
2488
2492 public function writeRenderedContent(
2493 string $a_content,
2494 string $a_md5
2495 ): void {
2496 global $DIC;
2497
2498 $db = $DIC->database();
2499
2500 $db->update("page_object", array(
2501 "rendered_content" => array("clob", $a_content),
2502 "render_md5" => array("text", $a_md5),
2503 "rendered_time" => array("timestamp", ilUtil::now())
2504 ), array(
2505 "page_id" => array("integer", $this->getId()),
2506 "lang" => array("text", $this->getLanguage()),
2507 "parent_type" => array("text", $this->getParentType())
2508 ));
2509 }
2510
2514 public static function getPagesWithLinks(
2515 string $a_parent_type,
2516 int $a_parent_id,
2517 string $a_lang = "-"
2518 ): array {
2519 global $DIC;
2520
2521 $db = $DIC->database();
2522
2523 $and_lang = "";
2524 if ($a_lang != "") {
2525 $and_lang = " AND lang = " . $db->quote($a_lang, "text");
2526 }
2527
2528 $q = "SELECT * FROM page_object " .
2529 " WHERE parent_id = " . $db->quote($a_parent_id, "integer") .
2530 " AND parent_type = " . $db->quote($a_parent_type, "text") .
2531 " AND int_links = " . $db->quote(1, "integer") . $and_lang;
2532 $set = $db->query($q);
2533 $pages = array();
2534 while ($page = $db->fetchAssoc($set)) {
2535 $key_add = ($a_lang == "")
2536 ? ":" . $page["lang"]
2537 : "";
2538 $pages[$page["page_id"] . $key_add] = array(
2539 "date" => $page["last_change"],
2540 "id" => $page["page_id"],
2541 "lang" => $page["lang"],
2542 "user" => $page["last_change_user"]
2543 );
2544 }
2545
2546 return $pages;
2547 }
2548
2552 public function containsIntLinks(string $a_content): bool
2553 {
2554 if (strpos($a_content, "IntLink")) {
2555 return true;
2556 }
2557 return false;
2558 }
2559
2563 public function performAutomaticModifications(): void
2564 {
2565 }
2566
2567 protected function getContentManager(): \ILIAS\COPage\Page\PageContentManager
2568 {
2569 $this->buildDom();
2570 return $this->page_manager->content($this->getDomDoc());
2571 }
2572
2577 string $a_type,
2578 int $a_id,
2579 string $a_target
2580 ): void {
2581 $cm = $this->getContentManager();
2582 $cm->setInitialOpenedContent($a_type, $a_id, $a_target);
2583 $this->update();
2584 }
2585
2589 public function getInitialOpenedContent(): array
2590 {
2591 $cm = $this->getContentManager();
2592 return $cm->getInitialOpenedContent();
2593 }
2594
2601 public function beforePageContentUpdate(ilPageContent $a_page_content): void
2602 {
2603 }
2604
2613 public function copy(
2614 int $a_id,
2615 string $a_parent_type = "",
2616 int $a_new_parent_id = 0,
2617 bool $a_clone_mobs = false,
2618 int $obj_copy_id = 0,
2619 bool $overwrite_existing = true
2620 ): void {
2621 if ($a_parent_type == "") {
2622 $a_parent_type = $this->getParentType();
2623 if ($a_new_parent_id == 0) {
2624 $a_new_parent_id = $this->getParentId();
2625 }
2626 }
2627
2628 foreach (self::lookupTranslations($this->getParentType(), $this->getId()) as $l) {
2629 $existed = false;
2630 $orig_page = ilPageObjectFactory::getInstance($this->getParentType(), $this->getId(), 0, $l);
2631 if (ilPageObject::_exists($a_parent_type, $a_id, $l)) {
2632 if (!$overwrite_existing) {
2633 continue;
2634 }
2635 $new_page_object = ilPageObjectFactory::getInstance($a_parent_type, $a_id, 0, $l);
2636 $existed = true;
2637 } else {
2638 $new_page_object = ilPageObjectFactory::getInstance($a_parent_type, 0, 0, $l);
2639 $new_page_object->setParentId($a_new_parent_id);
2640 $new_page_object->setId($a_id);
2641 }
2642 $new_page_object->setXMLContent($orig_page->copyXMLContent($a_clone_mobs, $a_new_parent_id, $obj_copy_id));
2643 $new_page_object->setActive($orig_page->getActive());
2644 $new_page_object->setActivationStart($orig_page->getActivationStart());
2645 $new_page_object->setActivationEnd($orig_page->getActivationEnd());
2646 $this->setCopyProperties($new_page_object);
2647 if ($existed) {
2648 $new_page_object->buildDom();
2649 $new_page_object->update();
2650 } else {
2651 $new_page_object->create(false);
2652 }
2653 }
2654 }
2655
2656 protected function setCopyProperties(ilPageObject $new_page): void
2657 {
2658 }
2659
2660
2664 public static function lookupTranslations(
2665 string $a_parent_type,
2666 int $a_id
2667 ): array {
2668 global $DIC;
2669
2670 $db = $DIC->database();
2671
2672 $set = $db->query(
2673 "SELECT lang FROM page_object " .
2674 " WHERE page_id = " . $db->quote($a_id, "integer") .
2675 " AND parent_type = " . $db->quote($a_parent_type, "text")
2676 );
2677 $langs = array();
2678 while ($rec = $db->fetchAssoc($set)) {
2679 $langs[] = $rec["lang"];
2680 }
2681 return $langs;
2682 }
2683
2687 public function copyPageToTranslation(
2688 string $a_target_lang
2689 ): void {
2690 $transl_page = ilPageObjectFactory::getInstance(
2691 $this->getParentType(),
2692 0,
2693 0,
2694 $a_target_lang
2695 );
2696 $this->setTranslationProperties($transl_page);
2697 $transl_page->create(false);
2698 }
2699
2700 protected function setTranslationProperties(self $transl_page): void
2701 {
2702 $transl_page->setId($this->getId());
2703 $transl_page->setParentId($this->getParentId());
2704 $transl_page->setXMLContent($this->copyXmlContent());
2705 $transl_page->setActive($this->getActive());
2706 $transl_page->setActivationStart($this->getActivationStart());
2707 $transl_page->setActivationEnd($this->getActivationEnd());
2708 }
2709
2710
2714
2718 public function getEditLock(): bool
2719 {
2720 $db = $this->db;
2721 $user = $this->user;
2722
2723 $min = $this->getEffectiveEditLockTime();
2724 if ($min > 0) {
2725 // try to set the lock for the user
2726 $ts = time();
2727 $db->manipulate(
2728 "UPDATE page_object SET " .
2729 " edit_lock_user = " . $db->quote($user->getId(), "integer") . "," .
2730 " edit_lock_ts = " . $db->quote($ts, "integer") .
2731 " WHERE (edit_lock_user = " . $db->quote($user->getId(), "integer") . " OR " .
2732 " edit_lock_ts < " . $db->quote(time() - ($min * 60), "integer") . ") " .
2733 " AND page_id = " . $db->quote($this->getId(), "integer") .
2734 " AND parent_type = " . $db->quote($this->getParentType(), "text")
2735 );
2736
2737 $set = $db->query(
2738 "SELECT edit_lock_user FROM page_object " .
2739 " WHERE page_id = " . $db->quote($this->getId(), "integer") .
2740 " AND parent_type = " . $db->quote($this->getParentType(), "text")
2741 );
2742 $rec = $db->fetchAssoc($set);
2743 if ($rec["edit_lock_user"] != $user->getId()) {
2744 return false;
2745 }
2746 }
2747
2748 return true;
2749 }
2750
2754 public function releasePageLock(): bool
2755 {
2756 $db = $this->db;
2757 $user = $this->user;
2758 $aset = new ilSetting("adve");
2759
2760 $min = (int) $aset->get("block_mode_minutes");
2761 if ($min > 0) {
2762 // try to set the lock for the user
2763 $ts = time();
2764 $db->manipulate(
2765 "UPDATE page_object SET " .
2766 " edit_lock_user = " . $db->quote($user->getId(), "integer") . "," .
2767 " edit_lock_ts = 0" .
2768 " WHERE edit_lock_user = " . $db->quote($user->getId(), "integer") .
2769 " AND page_id = " . $db->quote($this->getId(), "integer") .
2770 " AND parent_type = " . $db->quote($this->getParentType(), "text")
2771 );
2772
2773 $set = $db->query(
2774 "SELECT edit_lock_user FROM page_object " .
2775 " WHERE page_id = " . $db->quote($this->getId(), "integer") .
2776 " AND parent_type = " . $db->quote($this->getParentType(), "text")
2777 );
2778 $rec = $db->fetchAssoc($set);
2779 if ($rec["edit_lock_user"] != $user->getId()) {
2780 return false;
2781 }
2782 }
2783
2784 return true;
2785 }
2786
2790 public function getEditLockInfo(): array
2791 {
2792 $db = $this->db;
2793
2794 $aset = new ilSetting("adve");
2795 $min = (int) $aset->get("block_mode_minutes");
2796
2797 $set = $db->query(
2798 "SELECT edit_lock_user, edit_lock_ts FROM page_object " .
2799 " WHERE page_id = " . $db->quote($this->getId(), "integer") .
2800 " AND parent_type = " . $db->quote($this->getParentType(), "text")
2801 );
2802 $rec = $db->fetchAssoc($set);
2803 $rec["edit_lock_until"] = $rec["edit_lock_ts"] + $min * 60;
2804
2805 return $rec;
2806 }
2807
2812 public static function truncateHTML(
2813 string $a_text,
2814 int $a_length = 100,
2815 string $a_ending = '...',
2816 bool $a_exact = false,
2817 bool $a_consider_html = true
2818 ): string {
2819 $open_tags = [];
2820 if ($a_consider_html) {
2821 // if the plain text is shorter than the maximum length, return the whole text
2822 if (strlen(preg_replace('/<.*?>/', '', $a_text)) <= $a_length) {
2823 return $a_text;
2824 }
2825
2826 // splits all html-tags to scanable lines
2827 $total_length = strlen($a_ending);
2828 $open_tags = array();
2829 $truncate = '';
2830 preg_match_all('/(<.+?>)?([^<>]*)/s', $a_text, $lines, PREG_SET_ORDER);
2831 foreach ($lines as $line_matchings) {
2832 // if there is any html-tag in this line, handle it and add it (uncounted) to the output
2833 if (!empty($line_matchings[1])) {
2834 // if it's an "empty element" with or without xhtml-conform closing slash
2835 if (preg_match(
2836 '/^<(\s*.+?\/\s*|\s*(img|br|input|hr|area|base|basefont|col|frame|isindex|link|meta|param)(\s.+?)?)>$/is',
2837 $line_matchings[1]
2838 )) {
2839 // do nothing
2840 } // if tag is a closing tag
2841 elseif (preg_match('/^<\s*\/([^\s]+?)\s*>$/s', $line_matchings[1], $tag_matchings)) {
2842 // delete tag from $open_tags list
2843 $pos = array_search($tag_matchings[1], $open_tags);
2844 if ($pos !== false) {
2845 unset($open_tags[$pos]);
2846 }
2847 } // if tag is an opening tag
2848 elseif (preg_match('/^<\s*([^\s>!]+).*?>$/s', $line_matchings[1], $tag_matchings)) {
2849 // add tag to the beginning of $open_tags list
2850 array_unshift($open_tags, strtolower($tag_matchings[1]));
2851 }
2852 // add html-tag to $truncate'd text
2853 $truncate .= $line_matchings[1];
2854 }
2855
2856 // calculate the length of the plain text part of the line; handle entities as one character
2857 $content_length = strlen(preg_replace(
2858 '/&[0-9a-z]{2,8};|&#[0-9]{1,7};|[0-9a-f]{1,6};/i',
2859 ' ',
2860 $line_matchings[2]
2861 ));
2862 if ($total_length + $content_length > $a_length) {
2863 // the number of characters which are left
2864 $left = $a_length - $total_length;
2865 $entities_length = 0;
2866 // search for html entities
2867 if (preg_match_all(
2868 '/&[0-9a-z]{2,8};|&#[0-9]{1,7};|[0-9a-f]{1,6};/i',
2869 $line_matchings[2],
2870 $entities,
2871 PREG_OFFSET_CAPTURE
2872 )) {
2873 // calculate the real length of all entities in the legal range
2874 foreach ($entities[0] as $entity) {
2875 if ($entity[1] + 1 - $entities_length <= $left) {
2876 $left--;
2877 $entities_length += strlen($entity[0]);
2878 } else {
2879 // no more characters left
2880 break;
2881 }
2882 }
2883 }
2884
2885 // $truncate .= substr($line_matchings[2], 0, $left+$entities_length);
2886 $truncate .= ilStr::shortenText($line_matchings[2], 0, $left + $entities_length);
2887
2888 // maximum lenght is reached, so get off the loop
2889 break;
2890 } else {
2891 $truncate .= $line_matchings[2];
2892 $total_length += $content_length;
2893 }
2894
2895 // if the maximum length is reached, get off the loop
2896 if ($total_length >= $a_length) {
2897 break;
2898 }
2899 }
2900 } else {
2901 if (strlen($a_text) <= $a_length) {
2902 return $a_text;
2903 } else {
2904 // $truncate = substr($a_text, 0, $a_length - strlen($a_ending));
2905 $truncate = ilStr::shortenText($a_text, 0, $a_length - strlen($a_ending));
2906 }
2907 }
2908
2909 // THIS IS BUGGY AS IT MIGHT BREAK AN OPEN TAG AT THE END
2910 if (!count($open_tags)) {
2911 // if the words shouldn't be cut in the middle...
2912 if (!$a_exact) {
2913 // ...search the last occurance of a space...
2914 $spacepos = strrpos($truncate, ' ');
2915 if ($spacepos !== false) {
2916 // ...and cut the text in this position
2917 // $truncate = substr($truncate, 0, $spacepos);
2918 $truncate = ilStr::shortenText($truncate, 0, $spacepos);
2919 }
2920 }
2921 }
2922
2923 // add the defined ending to the text
2924 $truncate .= $a_ending;
2925
2926 if ($a_consider_html) {
2927 // close all unclosed html-tags
2928 foreach ($open_tags as $tag) {
2929 $truncate .= '</' . $tag . '>';
2930 }
2931 }
2932
2933 return $truncate;
2934 }
2935
2940 public function getContentTemplates(): array
2941 {
2942 return array();
2943 }
2944
2948 public static function getLastChangeByParent(
2949 string $a_parent_type,
2950 int $a_parent_id,
2951 string $a_lang = ""
2952 ): string {
2953 global $DIC;
2954
2955 $db = $DIC->database();
2956
2957 $and_lang = "";
2958 if ($a_lang != "") {
2959 $and_lang = " AND lang = " . $db->quote($a_lang, "text");
2960 }
2961
2962 $db->setLimit(1, 0);
2963 $q = "SELECT last_change FROM page_object " .
2964 " WHERE parent_id = " . $db->quote($a_parent_id, "integer") .
2965 " AND parent_type = " . $db->quote($a_parent_type, "text") . $and_lang .
2966 " ORDER BY last_change DESC";
2967
2968 $set = $db->query($q);
2969 $rec = $db->fetchAssoc($set);
2970
2971 return $rec["last_change"];
2972 }
2973
2975 {
2976 if ($this->getPageConfig()->getEditLockSupport() == false) {
2977 return 0;
2978 }
2979
2980 $aset = new ilSetting("adve");
2981 $min = (int) $aset->get("block_mode_minutes");
2982
2983 return $min;
2984 }
2985
2990 public function resolveResources(array $ref_mapping): bool
2991 {
2992 return ilPCResources::resolveResources($this, $ref_mapping);
2993 }
2994
2998 public function getRepoObjId(): ?int
2999 {
3000 return $this->getParentId();
3001 }
3002
3007 public function getPCModel(): array
3008 {
3009 $model = [];
3010 /*
3011 $this->log->debug("--- Get page model start");
3012 $model = [];
3013 foreach ($this->getAllPCIds() as $pc_id) {
3014 $co = $this->getContentObjectForPcId($pc_id);
3015 if ($co !== null) {
3016 $co_model = $co->getModel();
3017 if ($co_model !== null) {
3018 $model[$pc_id] = $co_model;
3019 }
3020 }
3021 }
3022 $this->log->debug("--- Get page model end");
3023 */
3024
3025 $config = $this->getPageConfig();
3026 foreach ($this->pc_definition->getPCDefinitions() as $def) {
3027 $model_provider = $this->pc_definition->getPCModelProviderByName($def["name"]);
3028 if ($config->getEnablePCType($def["name"]) || $def["name"] === "PlaceHolder") {
3029 if (!is_null($model_provider)) {
3030 foreach ($model_provider->getModels(
3031 $this->dom_util,
3032 $this
3033 ) as $pc_id => $co_model) {
3034 $model[$pc_id] = $co_model;
3035 }
3036 }
3037 }
3038 }
3039 return $model;
3040 }
3041
3049 public function assignCharacteristic(
3050 array $targets,
3051 string $char_par,
3052 string $char_sec,
3053 string $char_med
3054 ) {
3055 if (is_array($targets)) {
3056 foreach ($targets as $t) {
3057 $tarr = explode(":", $t);
3058 $cont_obj = $this->getContentObject($tarr[0], $tarr[1]);
3059 if (is_object($cont_obj) && $cont_obj->getType() == "par") {
3060 $cont_obj->setCharacteristic($char_par);
3061 }
3062 if (is_object($cont_obj) && $cont_obj->getType() == "sec") {
3063 $cont_obj->setCharacteristic($char_sec);
3064 }
3065 if (is_object($cont_obj) && $cont_obj->getType() == "media") {
3066 $cont_obj->setClass($char_med);
3067 }
3068 }
3069 return $this->update();
3070 }
3071 return true;
3072 }
3073}
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
$filename
Definition: buildRTE.php:78
const IL_CAL_UNIX
const IL_CAL_DATETIME
const IL_INSERT_AFTER
static sortArray(array $array, string $a_array_sortby_key, string $a_array_sortorder="asc", bool $a_numeric=false, bool $a_keep_keys=false)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static formatDate(ilDateTime $date, bool $a_skip_day=false, bool $a_include_wd=false, bool $include_seconds=false, ?ilObjUser $user=null,)
@classDescription Date and time handling
static _after(ilDateTime $start, ilDateTime $end, string $a_compare_field='', string $a_tz='')
compare two dates and check start is after end This method does not consider tz offsets.
static _before(ilDateTime $start, ilDateTime $end, string $a_compare_field='', string $a_tz='')
compare two dates and check start is before end This method does not consider tz offsets.
language handling
static getLogger(string $a_component_id)
Get component logger.
Component logger with individual log levels by component id.
static deleteNewsOfContext(int $a_context_obj_id, string $a_context_obj_type, int $a_context_sub_obj_id=0, string $a_context_sub_obj_type="")
Delete all news of a context.
static _getMobsOfObject(string $a_type, int $a_id, int $a_usage_hist_nr=0, string $a_lang="-")
static _deleteAllUsages(string $a_type, int $a_id, ?int $a_usage_hist_nr=0, string $a_lang="-")
User class.
static _lookupName(int $a_user_id)
parses the objects.xml it handles the xml-description of all ilias objects
static _lookupType(int $id, bool $reference=false)
static _exists(int $id, bool $reference=false, ?string $type=null)
checks if an object exists in object_data
static _getLastUpdateOfObjects(array $obj_ids)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Class ilPCParagraphGUI User Interface for Paragraph Editing.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static resolveResources(ilPageObject $page, array $ref_mappings)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Content object of ilPageObject (see ILIAS DTD).
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static getInstance(string $a_parent_type, int $a_id=0, int $a_old_nr=0, string $a_lang="-")
Get page object instance.
static getConfigInstance(string $a_parent_type)
Get page config instance.
Class ilPageObject Handles PageObjects of ILIAS Learning Modules (see ILIAS DTD)
releasePageLock()
Release page lock.
handleRepositoryLinksOnCopy(array $a_mapping, int $a_source_ref_id)
Handle repository links on copy process.
appendXMLContent(string $a_xml)
containsDeactivatedElements(string $a_content)
Check whether content contains deactivated elements.
getEditLockInfo()
Get edit lock info.
__beforeDelete()
Before deletion handler (internal).
create(bool $a_import=false)
create new page (with current xml data)
switchEnableMultiple(array $a_hids, bool $a_update=true, bool $a_self_ass=false)
(De-)activate elements
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...
insertContentNode(DOMNode $a_cont_node, string $a_pos, int $a_mode=IL_INSERT_AFTER, string $a_pcid="")
insert a content node before/after a sibling or as first child of a parent
setCopyProperties(ilPageObject $new_page)
deleteStyleUsages(int $a_old_nr=0)
Delete style usages.
getContentObjectForPcId(string $pcid)
Get content object for pc id.
getActive(bool $a_check_scheduled_activation=false)
deleteContent(string $a_hid, bool $a_update=true, string $a_pcid="", bool $move_operation=false)
delete content object with hierarchical id $a_hid
addFileSizes()
add file sizes
deleteInternalLinks()
Delete internal links.
setContentIdManager(\ILIAS\COPage\ID\ContentIdManager $content_id_manager)
setImportMode(bool $a_val)
ILIAS COPage Page PageManager $page_manager
getLanguageVariablesXML(int $style_id=0)
Get language variables as XML.
afterUpdate(DOMDocument $domdoc, string $xml)
After update.
ILIAS COPage PC DomainService $pc_service
getContentDomNode(string $a_hier_id, string $a_pc_id="")
update(bool $a_validate=true, bool $a_no_history=false)
update complete page content in db (dom xml content is used)
getPCIdsForHierIds(array $hier_ids)
Get hier ids for a set of pc ids.
setLastChange(string $a_lastchange)
getEditLock()
Get page lock.
containsIntLinks(string $a_content)
Check whether content contains internal links.
resolveQuestionReferences(array $a_mapping)
Resolve all quesiont references (after import)
needsImportParsing(?bool $a_parse=null)
cutContents(array $a_hids)
Copy contents to clipboard and cut them from the page.
static getLastChangeByParent(string $a_parent_type, int $a_parent_id, string $a_lang="")
Get all pages for parent object.
deleteContents(array $a_hids, bool $a_update=true, bool $a_self_ass=false, bool $move_operation=false)
Delete multiple content objects.
getHierIdForPcId(string $pcid)
registerOfflineHandler(object $handler)
ILIAS COPage ReadingTime ReadingTimeManager $reading_time_manager
getInitialOpenedContent()
Get initial opened content.
DOMDocument $dom
getLangVarXML(string $var)
getContentObject(string $a_hier_id, string $a_pc_id="")
Get a content object of the page.
static getNewPages(string $a_parent_type, int $a_parent_id, string $a_lang="-")
Get new pages.
getDuplicatePCIds()
Get all duplicate PC Ids.
increaseViewCnt()
Increase view cnt.
updateFromXML()
Updates page object with current xml content This function is currently (8 beta) called by:
getPCModel()
Get page component model.
getParentContentObjectForPcId(string $pcid)
Get parent content object for pc id.
copyXmlContent(bool $a_clone_mobs=false, int $a_new_parent_id=0, int $obj_copy_id=0, bool $self_ass=true)
Copy content of page; replace page components with copies where necessary (e.g.
setLanguage(string $a_val)
Set language.
static getAllPages(string $a_parent_type, int $a_parent_id, string $a_lang="-")
Get all pages for parent object.
copy(int $a_id, string $a_parent_type="", int $a_new_parent_id=0, bool $a_clone_mobs=false, int $obj_copy_id=0, bool $overwrite_existing=true)
Copy page.
setActivationStart(?string $a_activationstart)
getLastUpdateOfIncludedElements()
Get last update of included elements (media objects and files).
setLastChangeUser(int $a_val)
LOMServices $lom_services
ilObjectDefinition $obj_definition
getHistoryInfo(int $a_nr)
Get information about a history entry, its predecessor and its successor.
moveContentAfter(string $a_source, string $a_target, string $a_spcid="", string $a_tpcid="")
move content object from position $a_source before position $a_target (both hierarchical content ids)
ilDBInterface $db
pasteContents(string $a_hier_id, bool $a_self_ass=false)
Paste contents from pc clipboard.
containsIntLink()
returns true, if page was marked as containing an intern link (via setContainsIntLink) (this method s...
setContainsQuestion(bool $a_val)
static _writeActive(int $a_id, string $a_parent_type, bool $a_active)
write activation status
ILIAS COPage ID ContentIdManager $content_id_manager
__afterHistoryEntry(DOMDocument $a_old_domdoc, string $a_old_content, int $a_old_nr)
setRenderedTime(string $a_renderedtime)
copyPageToTranslation(string $a_target_lang)
Copy page to translation.
ILIAS COPage Dom DomUtil $dom_util
static truncateHTML(string $a_text, int $a_length=100, string $a_ending='...', bool $a_exact=false, bool $a_consider_html=true)
Truncate (html) string.
setContainsIntLink(bool $a_contains_link)
lm parser set this flag to true, if the page contains intern links (this method should only be called...
resolveIntLinks(?array $a_link_map=null)
Resolves all internal link targets of the page, if targets are available (after import)
getParagraphForPCID(string $pcid)
static _exists(string $a_parent_type, int $a_id, string $a_lang="", bool $a_no_cache=false)
Checks whether page exists.
getContentTemplates()
Get content templates.
static _isScheduledActivation(int $a_id, string $a_parent_type, string $a_lang="-")
Check whether page is activated by time schedule.
setPageConfig(ilPageConfig $a_val)
setRenderMd5(string $a_rendermd5)
resolveFileItems(array $a_mapping)
Resolve file items (after import)
getMultimediaXML(bool $offline=false)
get a xml string that contains all media object elements, that are referenced by any media alias in t...
checkPCIds()
Check, whether (all) page content hashes are set.
setActive(bool $a_active)
setShowActivationInfo(bool $a_val)
getDomDoc()
Get dom doc (DOMDocument)
ILIAS COPage Link LinkManager $link
getXMLFromDom(bool $a_incl_head=false, bool $a_append_mobs=false, bool $a_append_bib=false, string $a_append_str="", bool $a_omit_pageobject_tag=false, int $style_id=0, bool $offline=false)
get xml content of page from dom (use this, if any changes are made to the document)
getHistoryEntry(int $a_old_nr)
Get History Entry.
addHierIDs()
Add hierarchical ID (e.g.
setXMLContent(string $a_xml, string $a_encoding="UTF-8")
set xml content of page, start with <PageObject...>, end with </PageObject>, comply with ILIAS DTD,...
ILIAS COPage Style StyleManager $style_manager
buildDom(bool $a_force=false)
preparePageForCompare(ilPageObject $page)
getXMLContent(bool $a_incl_head=false)
get xml content of page
saveInternalLinks(DOMDocument $a_domdoc)
save internal links of page
sendParagraph(string $par_id, string $filename)
validateDom(bool $throw=false)
Validate the page content agains page DTD.
insertPCIds()
Insert Page Content IDs.
static getPagesWithLinks(string $a_parent_type, int $a_parent_id, string $a_lang="-")
Get all pages for parent object that contain internal links.
getAllPCIds()
Get all pc ids.
performAutomaticModifications()
Perform automatic modifications (may be overwritten by sub classes)
saveInitialOpenedContent(string $a_type, int $a_id, string $a_target)
Save initial opened content.
__afterUpdate(DOMDocument $a_domdoc, string $a_xml, bool $a_creation=false, bool $a_empty=false)
After update event handler (internal).
resolveIIMMediaAliases(array $a_mapping)
Resolve iim media aliases (in ilContObjParse)
assignCharacteristic(array $targets, string $char_par, string $char_sec, string $char_med)
Assign characteristic.
saveStyleUsage(DOMDocument $a_domdoc, int $a_old_nr=0)
Save all style class/template usages.
getHistoryEntries()
Get History Entries.
getDomNodeForPCId(string $pc_id)
static _lookupActive(int $a_id, string $a_parent_type, bool $a_check_scheduled_activation=false, string $a_lang="-")
lookup activation status
setParentId(int $a_id)
static _writeParentId(string $a_parent_type, int $a_pg_id, int $a_par_id)
writeRenderedContent(string $a_content, string $a_md5)
Write rendered content.
static _lookupActivationData(int $a_id, string $a_parent_type, string $a_lang="-")
Lookup activation data.
ILIAS COPage PC PCDefinition $pc_definition
getPCIdForHierId(string $hier_id)
static lookupParentId(int $a_id, string $a_type)
ilPageConfig $page_config
static getParentObjectContributors(string $a_parent_type, int $a_parent_id, string $a_lang="-")
Get all contributors for parent object.
createFromXML()
Create new page object with current xml content.
copyContents(array $a_hids)
Copy contents to clipboard.
static _existsAndNotEmpty(string $a_parent_type, int $a_id, string $a_lang="-")
Checks whether page exists and is not empty (may return true on some empty pages)
handleDeleteContent(?DOMNode $a_node=null, $move_operation=false)
Handle content before deletion This currently treats only plugged content If no node is given,...
static array $activation_data
resolveResources(array $ref_mapping)
Resolve resources.
setTranslationProperties(self $transl_page)
insertInstIntoIDs(string $a_inst, bool $a_res_ref_to_obj_id=true)
inserts installation id into ids (e.g.
static _lookupContainsDeactivatedElements(int $a_id, string $a_parent_type, string $a_lang="-")
lookup whether page contains deactivated elements
insertContent(ilPageContent $a_cont_obj, string $a_pos, int $a_mode=IL_INSERT_AFTER, string $a_pcid="", bool $remove_placeholder=true)
insert a content node before/after a sibling or as first child of a parent
getLangVarXMLForValue(string $var, string $val)
getMediaAliasElement(int $a_mob_id, int $a_nr=1)
get complete media object (alias) element
static lookupTranslations(string $a_parent_type, int $a_id)
Lookup translations.
static preloadActivationDataByParentId(int $a_parent_id)
Preload activation data by Parent Id.
getInternalLinks()
get all internal links that are used within the page
collectMediaObjects(bool $a_inline_only=true)
get all media objects, that are referenced and used within the page
moveIntLinks(array $a_from_to)
Move internal links from one destination to another.
getHierIdsForPCIds(array $a_pc_ids)
Get hier ids for a set of pc ids.
resolveMediaAliases(array $a_mapping, bool $a_reuse_existing_by_import=false)
Resolve media aliases (after import)
setActivationEnd(?string $a_activationend)
Set Activation End.
static getPageContributors(string $a_parent_type, int $a_page_id, string $a_lang="-")
Get all contributors for parent object.
static getRecentChanges(string $a_parent_type, int $a_parent_id, int $a_period=30, string $a_lang="")
Get recent pages changes for parent object.
setConcreteLang(string $a_val)
addUpdateListener(object $a_object, string $a_method, $a_parameters="")
beforePageContentUpdate(ilPageContent $a_page_content)
Before page content update Note: This one is "work in progress", currently only text paragraphs call ...
static array $exists
setRenderedContent(string $a_renderedcontent)
__construct(int $a_id=0, int $a_old_nr=0, string $a_lang="-")
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
ILIAS Setting Class.
static shortenText(string $a_string, int $a_start_pos, int $a_num_bytes, string $a_encoding='UTF-8')
Shorten text to the given number of bytes.
Definition: class.ilStr.php:99
Tree class data representation in hierachical trees using the Nested Set Model with Gaps by Joe Celco...
static getNamePresentation( $a_user_id, bool $a_user_image=false, bool $a_profile_link=false, string $a_profile_back_link='', bool $a_force_first_lastname=false, bool $a_omit_login=false, bool $a_sortable=true, bool $a_return_data_array=false, $a_ctrl_path=null)
Default behaviour is:
static now()
Return current timestamp in Y-m-d H:i:s format.
$c
Definition: deliver.php:25
return['delivery_method'=> 'php',]
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
$txt
Definition: error.php:31
const ILIAS_VERSION_NUMERIC
Interface ilDBInterface.
update(string $table_name, array $values, array $where)
@description $where MUST contain existing columns only.
setLimit(int $limit, int $offset=0)
quote($value, string $type)
manipulate(string $query)
Run a (write) Query on the database.
manipulateF(string $query, array $types, array $values)
query(string $query)
Run a (read-only) Query on the database.
fetchAssoc(ilDBStatement $statement)
queryF(string $query, array $types, array $values)
$path
Definition: ltiservices.php:30
$res
Definition: ltiservices.php:69
link(string $caption, string $href, bool $new_viewport=false)
Interface Observer \BackgroundTasks Contains several chained tasks and infos about them.
$handler
Definition: oai.php:29
if(!file_exists('../ilias.ini.php'))
global $DIC
Definition: shib_login.php:26
$q
Definition: shib_logout.php:23
$lm_set
getLanguage()
catch(ilCmiXapiException $e) send($response)
Definition: xapitoken.php:100