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