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