ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
class.ilPageObject.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (c) 1998-2009 ILIAS open source, Extended GPL, see docs/LICENSE */
3 
4 define("IL_INSERT_BEFORE", 0);
5 define("IL_INSERT_AFTER", 1);
6 define("IL_INSERT_CHILD", 2);
7 
8 define ("IL_CHAPTER_TITLE", "st_title");
9 define ("IL_PAGE_TITLE", "pg_title");
10 define ("IL_NO_HEADER", "none");
11 
15 /*
16  @todo 1
17 
18  - All PC types could be defined in service/module xml. (done)
19  -- type, class, directory (done)
20  -- internal links used/implemented?
21  -- styles used/implemented?
22  - application classes need
23  -- page object
24  --- page object should return php5 domdoc (getDom() vs getDomDoc()?)
25  esp. plugins should use this
26  -- remove content element hook, if content is not allowed
27  - PC types could move to components (e.g. blog, login)
28  - Problem: How to modularize xsl?
29  -- read from db?
30  -- xml entries say that xslt code is used -> read file and include in
31  main xslt file
32 
33 */
34 
46 abstract class ilPageObject
47 {
48  static $exists = array();
49 
50  var $id;
51  var $ilias;
52  var $dom;
53  var $xml;
54  var $encoding;
55  var $node;
56  var $cur_dtd = "ilias_pg_5_2.dtd";
66  var $language = "-";
67  static protected $activation_data = array();
68  protected $import_mode = false;
69 
73  protected $log;
74 
79  final public function __construct($a_id = 0, $a_old_nr = 0, $a_lang = "-")
80  {
81  global $ilias;
82 
83  $this->log = ilLoggerFactory::getLogger('copg');
84 
85  // @todo: move this elsewhere
86 // require_once("./Services/COPage/syntax_highlight/php/Beautifier/Init.php");
87 // require_once("./Services/COPage/syntax_highlight/php/Output/Output_css.php");
88 
89  $this->parent_type = $this->getParentType();
90  $this->id = $a_id;
91  $this->ilias = $ilias;
92  $this->setLanguage($a_lang);
93 
94  $this->contains_int_link = false;
95  $this->needs_parsing = false;
96  $this->update_listeners = array();
97  $this->update_listener_cnt = 0;
98  $this->dom_builded = false;
99  $this->page_not_found = false;
100  $this->old_nr = $a_old_nr;
101  $this->encoding = "UTF-8";
102  $this->id_elements =
103  array("PageContent", "TableRow", "TableData", "ListItem", "FileItem",
104  "Section", "Tab", "ContentPopup");
105  $this->setActive(true);
106  $this->show_page_act_info = false;
107 
108  if($a_id != 0)
109  {
110  $this->read();
111  }
112 
113  $this->initPageConfig();
114 
115  $this->afterConstructor();
116  }
117 
124  function afterConstructor()
125  {
126 
127  }
128 
129 
135  abstract function getParentType();
136 
142  final function initPageConfig()
143  {
144  include_once("./Services/COPage/classes/class.ilPageObjectFactory.php");
146  $this->setPageConfig($cfg);
147  }
148 
154  function setLanguage($a_val)
155  {
156  $this->language = $a_val;
157  }
158 
164  function getLanguage()
165  {
166  return $this->language;
167  }
168 
174  function setPageConfig($a_val)
175  {
176  $this->page_config = $a_val;
177  }
178 
184  function getPageConfig()
185  {
186  return $this->page_config;
187  }
188 
194  function setRenderMd5($a_rendermd5)
195  {
196  $this->rendermd5 = $a_rendermd5;
197  }
198 
204  function getRenderMd5()
205  {
206  return $this->rendermd5;
207  }
208 
214  function setRenderedContent($a_renderedcontent)
215  {
216  $this->renderedcontent = $a_renderedcontent;
217  }
218 
225  {
226  return $this->renderedcontent;
227  }
228 
234  function setRenderedTime($a_renderedtime)
235  {
236  $this->renderedtime = $a_renderedtime;
237  }
238 
244  function getRenderedTime()
245  {
246  return $this->renderedtime;
247  }
248 
254  function setLastChange($a_lastchange)
255  {
256  $this->lastchange = $a_lastchange;
257  }
258 
264  function getLastChange()
265  {
266  return $this->lastchange;
267  }
268 
274  public function setLastChangeUser($a_val)
275  {
276  $this->last_change_user = $a_val;
277  }
278 
284  public function getLastChangeUser()
285  {
286  return $this->last_change_user;
287  }
288 
294  function setShowActivationInfo($a_val)
295  {
296  $this->show_page_act_info = $a_val;
297  }
298 
305  {
306  return $this->show_page_act_info;
307  }
308 
312  function read()
313  {
314  global $ilDB;
315 
316  $this->setActive(true);
317  if ($this->old_nr == 0)
318  {
319  $query = "SELECT * FROM page_object".
320  " WHERE page_id = ".$ilDB->quote($this->id, "integer").
321  " AND parent_type=".$ilDB->quote($this->getParentType(), "text").
322  " AND lang = ".$ilDB->quote($this->getLanguage(), "text");
323  $pg_set = $this->ilias->db->query($query);
324  $this->page_record = $ilDB->fetchAssoc($pg_set);
325  $this->setActive($this->page_record["active"]);
326  $this->setActivationStart($this->page_record["activation_start"]);
327  $this->setActivationEnd($this->page_record["activation_end"]);
328  $this->setShowActivationInfo($this->page_record["show_activation_info"]);
329  }
330  else
331  {
332  $query = "SELECT * FROM page_history".
333  " WHERE page_id = ".$ilDB->quote($this->id, "integer").
334  " AND parent_type=".$ilDB->quote($this->getParentType(), "text").
335  " AND nr = ".$ilDB->quote((int) $this->old_nr, "integer").
336  " AND lang = ".$ilDB->quote($this->getLanguage(), "text");
337  $pg_set = $ilDB->query($query);
338  $this->page_record = $ilDB->fetchAssoc($pg_set);
339  }
340  if (!$this->page_record)
341  {
342  include_once("./Services/COPage/exceptions/class.ilCOPageNotFoundException.php");
343  throw new ilCOPageNotFoundException("Error: Page ".$this->id." is not in database".
344  " (parent type ".$this->getParentType().", lang: ".$this->getLanguage().").");
345  }
346 
347  $this->xml = $this->page_record["content"];
348  $this->setParentId($this->page_record["parent_id"]);
349  $this->last_change_user = $this->page_record["last_change_user"];
350  $this->create_user = $this->page_record["create_user"];
351  $this->setRenderedContent($this->page_record["rendered_content"]);
352  $this->setRenderMd5($this->page_record["render_md5"]);
353  $this->setRenderedTime($this->page_record["rendered_time"]);
354  $this->setLastChange($this->page_record["last_change"]);
355 
356  }
357 
365  static function _exists($a_parent_type, $a_id, $a_lang = "", $a_no_cache = false)
366  {
367  global $ilDB;
368  if (!$a_no_cache && isset(self::$exists[$a_parent_type.":".$a_id.":".$a_lang]))
369  {
370  return self::$exists[$a_parent_type.":".$a_id.":".$a_lang];
371  }
372 
373  $and_lang = "";
374  if ($a_lang != "")
375  {
376  $and_lang = " AND lang = ".$ilDB->quote($a_lang, "text");
377  }
378 
379  $query = "SELECT page_id FROM page_object WHERE page_id = ".$ilDB->quote($a_id, "integer")." ".
380  "AND parent_type = ".$ilDB->quote($a_parent_type, "text").$and_lang;
381  $set = $ilDB->query($query);
382  if ($row = $ilDB->fetchAssoc($set))
383  {
384  self::$exists[$a_parent_type.":".$a_id.":".$a_lang] = true;
385  return true;
386  }
387  else
388  {
389  self::$exists[$a_parent_type.":".$a_id.":".$a_lang] = false;
390  return false;
391  }
392  }
393 
401  static function _existsAndNotEmpty($a_parent_type, $a_id, $a_lang = "-")
402  {
403  global $ilDB;
404 
405  include_once("./Services/COPage/classes/class.ilPageUtil.php");
406 
407  return ilPageUtil::_existsAndNotEmpty($a_parent_type, $a_id, $a_lang);
408  }
409 
410  function buildDom($a_force = false)
411  {
412  if ($this->dom_builded && !$a_force)
413  {
414  return;
415  }
416 
417 //echo "\n<br>buildDomWith:".$this->getId().":xml:".$this->getXMLContent(true).":<br>";
418 
419  $options = 0;
420  //$options = DOMXML_LOAD_VALIDATING;
421  //$options = LIBXML_DTDLOAD;
422  //$options = LIBXML_NOXMLDECL;
423 //echo htmlentities($this->getXMLContent(true))."<br>";
424  $this->dom = @domxml_open_mem($this->getXMLContent(true), $options, $error);
425 //var_dump($error);
426  $xpc = xpath_new_context($this->dom);
427  $path = "//PageObject";
428  $res = xpath_eval($xpc, $path);
429  if (count($res->nodeset) == 1)
430  {
431 // echo "h";
432  $this->node = $res->nodeset[0];
433  }
434 //echo htmlentities($this->dom->dump_node($this->node)); exit;
435 
436  if (empty($error))
437  {
438  $this->dom_builded = true;
439  return true;
440  }
441  else
442  {
443  return $error;
444  }
445  }
446 
447  function freeDom()
448  {
449  //$this->dom->free();
450  unset($this->dom);
451  }
452 
456  function getDom()
457  {
458  return $this->dom;
459  }
460 
467  function getDomDoc()
468  {
469  if ($this->dom instanceof php4DOMDocument)
470  {
471  return $this->dom->myDOMDocument;
472  }
473 
474  return $this->dom;
475  }
476 
477 
481  function setId($a_id)
482  {
483  $this->id = $a_id;
484  }
485 
486  function getId()
487  {
488  return $this->id;
489  }
490 
491  function setParentId($a_id)
492  {
493  $this->parent_id = $a_id;
494  }
495 
496  function getParentId()
497  {
498  return $this->parent_id;
499  }
500 
501  function addUpdateListener(&$a_object, $a_method, $a_parameters = "")
502  {
504  $this->update_listeners[$cnt]["object"] = $a_object;
505  $this->update_listeners[$cnt]["method"] = $a_method;
506  $this->update_listeners[$cnt]["parameters"] = $a_parameters;
507  $this->update_listener_cnt++;
508  }
509 
511  {
512  for($i=0; $i<$this->update_listener_cnt; $i++)
513  {
514  $object = $this->update_listeners[$i]["object"];
515  $method = $this->update_listeners[$i]["method"];
516  $parameters = $this->update_listeners[$i]["parameters"];
517  $object->$method($parameters);
518  }
519  }
520 
526  function setActive($a_active)
527  {
528  $this->active = $a_active;
529  }
530 
536  function getActive($a_check_scheduled_activation = false)
537  {
538  if ($a_check_scheduled_activation && !$this->active)
539  {
540  include_once("./Services/Calendar/classes/class.ilDateTime.php");
542  $end = new ilDateTime($this->getActivationEnd(), IL_CAL_DATETIME);
543  $now = new ilDateTime(time(), IL_CAL_UNIX);
544  if (!ilDateTime::_before($now, $start) && !ilDateTime::_after($now, $end))
545  {
546  return true;
547  }
548  }
549  return $this->active;
550  }
551 
557  static function preloadActivationDataByParentId($a_parent_id)
558  {
559  global $ilDB;
560 
561  $set = $ilDB->query("SELECT page_id, parent_type, lang, active, activation_start, activation_end, show_activation_info FROM page_object ".
562  " WHERE parent_id = ".$ilDB->quote($a_parent_id, "integer")
563  );
564  while ($rec = $ilDB->fetchAssoc($set))
565  {
566  self::$activation_data[$rec["page_id"].":".$rec["parent_type"].":".$rec["lang"]] = $rec;
567  }
568  }
569 
570 
574  static function _lookupActive($a_id, $a_parent_type, $a_check_scheduled_activation = false, $a_lang = "-")
575  {
576  global $ilDB;
577 
578  // language must be set at least to "-"
579  if ($a_lang == "")
580  {
581  $a_lang = "-";
582  }
583 
584  if (isset(self::$activation_data[$a_id.":".$a_parent_type.":".$a_lang]))
585  {
586  $rec = self::$activation_data[$a_id.":".$a_parent_type.":".$a_lang];
587  }
588  else
589  {
590  $set = $ilDB->queryF("SELECT active, activation_start, activation_end FROM page_object WHERE page_id = %s".
591  " AND parent_type = %s AND lang = %s",
592  array("integer", "text", "text"),
593  array($a_id, $a_parent_type, $a_lang));
594  $rec = $ilDB->fetchAssoc($set);
595  }
596 
597 
598  $rec["n"] = ilUtil::now();
599 
600  if (!$rec["active"] && $a_check_scheduled_activation)
601  {
602  if ($rec["n"] >= $rec["activation_start"] &&
603  $rec["n"] <= $rec["activation_end"])
604  {
605  return true;
606  }
607  }
608 
609  return $rec["active"];
610  }
611 
615  static function _isScheduledActivation($a_id, $a_parent_type, $a_lang = "-")
616  {
617  global $ilDB;
618 
619  // language must be set at least to "-"
620  if ($a_lang == "")
621  {
622  $a_lang = "-";
623  }
624 
625 //echo "<br>";
626 //var_dump(self::$activation_data); exit;
627  if (isset(self::$activation_data[$a_id.":".$a_parent_type.":".$a_lang]))
628  {
629  $rec = self::$activation_data[$a_id.":".$a_parent_type.":".$a_lang];
630  }
631  else
632  {
633  $set = $ilDB->queryF("SELECT active, activation_start, activation_end FROM page_object WHERE page_id = %s".
634  " AND parent_type = %s AND lang = %s", array("integer", "text", "text"),
635  array($a_id, $a_parent_type, $a_lang));
636  $rec = $ilDB->fetchAssoc($set);
637  }
638 
639  if (!$rec["active"] && $rec["activation_start"] != "")
640  {
641  return true;
642  }
643 
644  return false;
645  }
646 
650  static function _writeActive($a_id, $a_parent_type, $a_active, $a_reset_scheduled_activation = true, $a_lang = "-")
651  {
652  global $ilDB;
653 
654  // language must be set at least to "-"
655  if ($a_lang == "")
656  {
657  $a_lang = "-";
658  }
659 
660  if ($a_reset_scheduled_activation)
661  {
662  $st = $ilDB->manipulateF("UPDATE page_object SET active = %s, activation_start = %s, ".
663  " activation_end = %s WHERE page_id = %s".
664  " AND parent_type = %s AND lang = %s", array("boolean", "timestamp", "timestamp", "integer", "text", "text"),
665  array($a_active, null, null, $a_id, $a_parent_type, $a_lang));
666  }
667  else
668  {
669  $st = $ilDB->prepareManip("UPDATE page_object SET active = %s WHERE page_id = %s".
670  " AND parent_type = %s AND lang = %s", array("boolean", "integer", "text", "text"),
671  array($a_active, $a_id, $a_parent_type, $a_lang));
672  }
673  }
674 
678  static function _lookupActivationData($a_id, $a_parent_type, $a_lang = "-")
679  {
680  global $ilDB;
681 
682  // language must be set at least to "-"
683  if ($a_lang == "")
684  {
685  $a_lang = "-";
686  }
687 
688  if (isset(self::$activation_data[$a_id.":".$a_parent_type.":".$a_lang]))
689  {
690  $rec = self::$activation_data[$a_id.":".$a_parent_type.":".$a_lang];
691  }
692  else
693  {
694  $set = $ilDB->queryF("SELECT active, activation_start, activation_end, show_activation_info FROM page_object WHERE page_id = %s".
695  " AND parent_type = %s AND lang = %s",
696  array("integer", "text", "text"),
697  array($a_id, $a_parent_type, $a_lang));
698  $rec = $ilDB->fetchAssoc($set);
699  }
700 
701  return $rec;
702  }
703 
704 
708  static function lookupParentId($a_id, $a_type)
709  {
710  global $ilDB;
711 
712  $res = $ilDB->query("SELECT parent_id FROM page_object WHERE page_id = ".$ilDB->quote($a_id, "integer")." ".
713  "AND parent_type=".$ilDB->quote($a_type, "text"));
714  $rec = $ilDB->fetchAssoc($res);
715  return $rec["parent_id"];
716  }
717 
721  static function _writeParentId($a_parent_type, $a_pg_id, $a_par_id)
722  {
723  global $ilDB;
724 
725  $st = $ilDB->manipulateF("UPDATE page_object SET parent_id = %s WHERE page_id = %s".
726  " AND parent_type = %s", array("integer", "integer", "text"),
727  array($a_par_id, $a_pg_id, $a_parent_type));
728  }
729 
735  function setActivationStart($a_activationstart)
736  {
737  if ($a_activationstart == "")
738  {
739  $a_activationstart = null;
740  }
741  $this->activationstart = $a_activationstart;
742  }
743 
750  {
751  return $this->activationstart;
752  }
753 
759  function setActivationEnd($a_activationend)
760  {
761  if ($a_activationend == "")
762  {
763  $a_activationend = null;
764  }
765  $this->activationend = $a_activationend;
766  }
767 
773  function getActivationEnd()
774  {
775  return $this->activationend;
776  }
777 
786  function getContentObject($a_hier_id, $a_pc_id = "")
787  {
788  $cont_node = $this->getContentNode($a_hier_id, $a_pc_id);
789  if (!is_object($cont_node))
790  {
791  return false;
792  }
793  include_once("./Services/COPage/classes/class.ilCOPagePCDef.php");
794  $node_name = $cont_node->node_name();
795  if ($node_name == "PageObject")
796  {
797  return null;
798  }
799  if ($node_name == "PageContent")
800  {
801  $child_node = $cont_node->first_child();
802  $node_name = $child_node->node_name();
803  }
804 
805  // table extra handling (@todo: get rid of it)
806  if ($node_name == "Table")
807  {
808  if ($child_node->get_attribute("DataTable") == "y")
809  {
810  require_once("./Services/COPage/classes/class.ilPCDataTable.php");
811  $tab = new ilPCDataTable($this);
812  $tab->setNode($cont_node);
813  $tab->setHierId($a_hier_id);
814  }
815  else
816  {
817  require_once("./Services/COPage/classes/class.ilPCTable.php");
818  $tab = new ilPCTable($this);
819  $tab->setNode($cont_node);
820  $tab->setHierId($a_hier_id);
821  }
822  $tab->setPcId($a_pc_id);
823  return $tab;
824  }
825 
826  // media extra handling (@todo: get rid of it)
827  if ($node_name == "MediaObject")
828  {
829  if ($_GET["pgEdMediaMode"] != "") {echo "ilPageObject::error media"; exit;}
830 
831  //require_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
832  require_once("./Services/COPage/classes/class.ilPCMediaObject.php");
833 
834  $mal_node = $child_node->first_child();
835 //echo "ilPageObject::getContentObject:nodename:".$mal_node->node_name().":<br>";
836  $id_arr = explode("_", $mal_node->get_attribute("OriginId"));
837  $mob_id = $id_arr[count($id_arr) - 1];
838 
839  // allow deletion of non-existing media objects
840  if (!ilObject::_exists($mob_id) && in_array("delete", $_POST))
841  {
842  $mob_id = 0;
843  }
844 
845  //$mob = new ilObjMediaObject($mob_id);
846  $mob = new ilPCMediaObject($this);
847  $mob->readMediaObject($mob_id);
848 
849  //$mob->setDom($this->dom);
850  $mob->setNode($cont_node);
851  $mob->setHierId($a_hier_id);
852  $mob->setPcId($a_pc_id);
853  return $mob;
854  }
855 
856  //
857  // generic procedure
858  //
859 
860  $pc_def = ilCOPagePCDef::getPCDefinitionByName($node_name);
861 
862  // check if pc definition has been found
863  if (!is_array($pc_def))
864  {
865  include_once("./Services/COPage/exceptions/class.ilCOPageUnknownPCTypeException.php");
866  throw new ilCOPageUnknownPCTypeException('Unknown PC Name "'.$node_name.'".');
867  }
868  $pc_class = "ilPC".$pc_def["name"];
869  $pc_path = "./".$pc_def["component"]."/".$pc_def["directory"]."/class.".$pc_class.".php";
870  require_once($pc_path);
871  $pc = new $pc_class($this);
872  $pc->setNode($cont_node);
873  $pc->setHierId($a_hier_id);
874  $pc->setPcId($a_pc_id);
875  return $pc;
876  }
877 
884  function &getContentNode($a_hier_id, $a_pc_id = "")
885  {
886  $xpc = xpath_new_context($this->dom);
887  if($a_hier_id == "pg")
888  {
889  return $this->node;
890  }
891  else
892  {
893  // get per pc id
894  if ($a_pc_id != "")
895  {
896  $path = "//*[@PCID = '$a_pc_id']";
897  $res = xpath_eval($xpc, $path);
898  if (count($res->nodeset) == 1)
899  {
900  $cont_node = $res->nodeset[0];
901  return $cont_node;
902  }
903  }
904 
905  // fall back to hier id
906  $path = "//*[@HierId = '$a_hier_id']";
907  $res = xpath_eval($xpc, $path);
908  if (count($res->nodeset) == 1)
909  {
910  $cont_node = $res->nodeset[0];
911  return $cont_node;
912  }
913  }
914  }
915 
922  function checkForTag($a_content_tag, $a_hier_id, $a_pc_id = "")
923  {
924  $xpc = xpath_new_context($this->dom);
925  // get per pc id
926  if ($a_pc_id != "")
927  {
928  $path = "//*[@PCID = '$a_pc_id']//".$a_content_tag;
929  $res = xpath_eval($xpc, $path);
930  if (count($res->nodeset) > 0)
931  {
932  return true;
933  }
934  }
935 
936  // fall back to hier id
937  $path = "//*[@HierId = '$a_hier_id']//".$a_content_tag;
938  $res = xpath_eval($xpc, $path);
939  if (count($res->nodeset) > 0)
940  {
941  return true;
942  }
943  return false;
944  }
945 
946  // only for test purposes
947  function lookforhier($a_hier_id)
948  {
949  $xpc = xpath_new_context($this->dom);
950  $path = "//*[@HierId = '$a_hier_id']";
951  $res = xpath_eval($xpc, $path);
952  if (count($res->nodeset) == 1)
953  return "YES";
954  else
955  return "NO";
956  }
957 
958 
959  function &getNode()
960  {
961  return $this->node;
962  }
963 
964 
973  function setXMLContent($a_xml, $a_encoding = "UTF-8")
974  {
975  $this->encoding = $a_encoding;
976  $this->xml = $a_xml;
977  }
978 
985  function appendXMLContent($a_xml)
986  {
987  $this->xml.= $a_xml;
988  }
989 
990 
994  function getXMLContent($a_incl_head = false)
995  {
996  // build full http path for XML DOCTYPE header.
997  // Under windows a relative path doesn't work :-(
998  if($a_incl_head)
999  {
1000 //echo "+".$this->encoding."+";
1001  $enc_str = (!empty($this->encoding))
1002  ? "encoding=\"".$this->encoding."\""
1003  : "";
1004  return "<?xml version=\"1.0\" $enc_str ?>".
1005  "<!DOCTYPE PageObject SYSTEM \"".ILIAS_ABSOLUTE_PATH."/xml/".$this->cur_dtd."\">".
1006  $this->xml;
1007  }
1008  else
1009  {
1010  return $this->xml;
1011  }
1012  }
1013 
1018  function copyXmlContent($a_clone_mobs = false)
1019  {
1020  $xml = $this->getXmlContent();
1021  $temp_dom = domxml_open_mem('<?xml version="1.0" encoding="UTF-8"?>'.$xml,
1022  DOMXML_LOAD_PARSING, $error);
1023  if(empty($error))
1024  {
1025  $this->handleCopiedContent($temp_dom, true, $a_clone_mobs);
1026  }
1027  $xml = $temp_dom->dump_mem(0, $this->encoding);
1028  $xml = preg_replace('/<\?xml[^>]*>/i',"",$xml);
1029  $xml = preg_replace('/<!DOCTYPE[^>]*>/i',"",$xml);
1030 
1031  return $xml;
1032  }
1033 
1034 // @todo 1: begin: generalize, remove concrete dependencies
1035 
1045  function handleCopiedContent($a_dom, $a_self_ass = true, $a_clone_mobs = false)
1046  {
1047  include_once("./Services/COPage/classes/class.ilCOPagePCDef.php");
1049 
1050  // handle question elements
1051  if ($a_self_ass)
1052  {
1053  $this->newQuestionCopies($a_dom);
1054  }
1055  else
1056  {
1057  $this->removeQuestions($a_dom);
1058  }
1059 
1060  // handle interactive images
1061  $this->newIIMCopies($a_dom);
1062 
1063  // handle media objects
1064  if ($a_clone_mobs)
1065  {
1066  $this->newMobCopies($a_dom);
1067  }
1068 
1069 // @todo 1: move all functions from above to the new domdoc
1070  if ($a_dom instanceof php4DOMDocument)
1071  {
1072  $a_dom = $a_dom->myDOMDocument;
1073  }
1074  foreach ($defs as $def)
1075  {
1077  $cl = $def["pc_class"];
1078  $cl::handleCopiedContent($a_dom, $a_self_ass, $a_clone_mobs);
1079  }
1080 
1081  }
1082 
1087  function newIIMCopies($temp_dom)
1088  {
1089  // Get question IDs
1090  $path = "//InteractiveImage/MediaAlias";
1091  $xpc = xpath_new_context($temp_dom);
1092  $res = & xpath_eval($xpc, $path);
1093 
1094  $q_ids = array();
1095  include_once("./Services/Link/classes/class.ilInternalLink.php");
1096  for ($i = 0; $i < count ($res->nodeset); $i++)
1097  {
1098  $or_id = $res->nodeset[$i]->get_attribute("OriginId");
1099 
1100  $inst_id = ilInternalLink::_extractInstOfTarget($or_id);
1101  $mob_id = ilInternalLink::_extractObjIdOfTarget($or_id);
1102 
1103  if (!($inst_id > 0))
1104  {
1105  if ($mob_id > 0)
1106  {
1107  include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
1108  $media_object = new ilObjMediaObject($mob_id);
1109 
1110  // now copy this question and change reference to
1111  // new question id
1112  $new_mob = $media_object->duplicate();
1113 
1114  $res->nodeset[$i]->set_attribute("OriginId", "il__mob_".$new_mob->getId());
1115  }
1116  }
1117  }
1118  }
1119 
1123  function newMobCopies($temp_dom)
1124  {
1125  // Get question IDs
1126  $path = "//MediaObject/MediaAlias";
1127  $xpc = xpath_new_context($temp_dom);
1128  $res = & xpath_eval($xpc, $path);
1129 
1130  $q_ids = array();
1131  include_once("./Services/Link/classes/class.ilInternalLink.php");
1132  for ($i = 0; $i < count ($res->nodeset); $i++)
1133  {
1134  $or_id = $res->nodeset[$i]->get_attribute("OriginId");
1135 
1136  $inst_id = ilInternalLink::_extractInstOfTarget($or_id);
1137  $mob_id = ilInternalLink::_extractObjIdOfTarget($or_id);
1138 
1139  if (!($inst_id > 0))
1140  {
1141  if ($mob_id > 0)
1142  {
1143  include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
1144  $media_object = new ilObjMediaObject($mob_id);
1145 
1146  // now copy this question and change reference to
1147  // new question id
1148  $new_mob = $media_object->duplicate();
1149 
1150  $res->nodeset[$i]->set_attribute("OriginId", "il__mob_".$new_mob->getId());
1151  }
1152  }
1153  }
1154  }
1155 
1160  function newQuestionCopies(&$temp_dom)
1161  {
1162  // Get question IDs
1163  $path = "//Question";
1164  $xpc = xpath_new_context($temp_dom);
1165  $res = & xpath_eval($xpc, $path);
1166 
1167  $q_ids = array();
1168  include_once("./Services/Link/classes/class.ilInternalLink.php");
1169  for ($i = 0; $i < count ($res->nodeset); $i++)
1170  {
1171  $qref = $res->nodeset[$i]->get_attribute("QRef");
1172 
1173  $inst_id = ilInternalLink::_extractInstOfTarget($qref);
1175 
1176  if (!($inst_id > 0))
1177  {
1178  if ($q_id > 0)
1179  {
1180  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
1181  $question = assQuestion::_instantiateQuestion($q_id);
1182  // check due to #16557
1183  if (is_object($question) && $question->isComplete())
1184  {
1185  // check if page for question exists
1186  // due to a bug in early 4.2.x version this is possible
1187  if (!ilPageObject::_exists("qpl", $q_id))
1188  {
1189  $question->createPageObject();
1190  }
1191 
1192  // now copy this question and change reference to
1193  // new question id
1194  $duplicate_id = $question->duplicate(false);
1195  $res->nodeset[$i]->set_attribute("QRef", "il__qst_".$duplicate_id);
1196  }
1197  }
1198  }
1199  }
1200  }
1201 
1208  function removeQuestions(&$temp_dom)
1209  {
1210  // Get question IDs
1211  $path = "//Question";
1212  $xpc = xpath_new_context($temp_dom);
1213  $res = & xpath_eval($xpc, $path);
1214  for ($i = 0; $i < count ($res->nodeset); $i++)
1215  {
1216  $parent_node = $res->nodeset[$i]->parent_node();
1217  $parent_node->unlink_node($parent_node);
1218  }
1219  }
1220 
1221 // @todo: end
1222 
1230  {
1231  // Get question IDs
1232  $this->buildDom();
1233  $path = "//PageContent";
1234  $xpc = xpath_new_context($this->dom);
1235  $res = & xpath_eval($xpc, $path);
1236  return count ($res->nodeset);
1237  }
1238 
1243  function getXMLFromDom($a_incl_head = false, $a_append_mobs = false, $a_append_bib = false,
1244  $a_append_str = "", $a_omit_pageobject_tag = false)
1245  {
1246  if ($a_incl_head)
1247  {
1248 //echo "\n<br>#".$this->encoding."#";
1249  return $this->dom->dump_mem(0, $this->encoding);
1250  }
1251  else
1252  {
1253  // append multimedia object elements
1254  if ($a_append_mobs || $a_append_bib || $a_append_link_info)
1255  {
1256  $mobs = "";
1257  $bibs = "";
1258  if ($a_append_mobs)
1259  {
1260  $mobs = $this->getMultimediaXML();
1261  }
1262  if ($a_append_bib)
1263  {
1264 // deprecated
1265 // $bibs = $this->getBibliographyXML();
1266  }
1267  $trans = $this->getLanguageVariablesXML();
1268  //echo htmlentities($this->dom->dump_node($this->node)); exit;
1269  return "<dummy>".$this->dom->dump_node($this->node).$mobs.$bibs.$trans.$a_append_str."</dummy>";
1270  }
1271  else
1272  {
1273  if (is_object($this->dom))
1274  {
1275  if ($a_omit_pageobject_tag)
1276  {
1277  $xml = "";
1278  $childs = $this->node->child_nodes();
1279  for($i = 0; $i < count($childs); $i++)
1280  {
1281  $xml.= $this->dom->dump_node($childs[$i]);
1282  }
1283  return $xml;
1284  }
1285  else
1286  {
1287  $xml = $this->dom->dump_mem(0, $this->encoding);
1288  $xml = preg_replace('/<\?xml[^>]*>/i',"",$xml);
1289  $xml = preg_replace('/<!DOCTYPE[^>]*>/i',"",$xml);
1290  return $xml;
1291 
1292  // don't use dump_node. This gives always entities.
1293  //return $this->dom->dump_node($this->node);
1294  }
1295  }
1296  else
1297  {
1298  return "";
1299  }
1300  }
1301  }
1302  }
1303 
1308  {
1309  global $lng;
1310 
1311  $xml = "<LVs>";
1312  $lang_vars = array(
1313  "ed_paste_clip", "ed_edit", "ed_edit_prop", "ed_delete", "ed_moveafter",
1314  "ed_movebefore", "ed_go", "ed_class", "ed_width", "ed_align_left",
1315  "ed_align_right", "ed_align_center", "ed_align_left_float",
1316  "ed_align_right_float", "ed_delete_item", "ed_new_item_before",
1317  "ed_new_item_after", "ed_copy_clip", "please_select", "ed_split_page",
1318  "ed_item_up", "ed_item_down", "ed_split_page_next","ed_enable",
1319  "de_activate", "ed_paste", "ed_edit_multiple", "ed_cut", "ed_copy", "ed_insert_templ",
1320  "ed_click_to_add_pg", "download");
1321 
1322  // collect lang vars from pc elements
1323  include_once("./Services/COPage/classes/class.ilCOPagePCDef.php");
1325  foreach ($defs as $def)
1326  {
1327  $lang_vars[] = "pc_".$def["pc_type"];
1328  $lang_vars[] = "ed_insert_".$def["pc_type"];
1329 
1331  $cl = $def["pc_class"];
1332  $lvs = call_user_func($def["pc_class"].'::getLangVars');
1333  foreach ($lvs as $lv)
1334  {
1335  $lang_vars[] = $lv;
1336  }
1337  }
1338 
1339  foreach ($lang_vars as $lang_var)
1340  {
1341  $this->appendLangVarXML($xml, $lang_var);
1342  }
1343 
1344  $xml.= "</LVs>";
1345 
1346  return $xml;
1347  }
1348 
1349  function appendLangVarXML(&$xml, $var)
1350  {
1351  global $lng;
1352 
1353  $xml.= "<LV name=\"$var\" value=\"".$lng->txt("cont_".$var)."\"/>";
1354  }
1355 
1356 // @todo begin: move this to paragraph class
1357 
1359  {
1360  if($this->dom)
1361  {
1362  require_once("./Services/COPage/classes/class.ilPCParagraph.php");
1363  $xpc = xpath_new_context($this->dom);
1364  $path = "//Paragraph[1]";
1365  $res = xpath_eval($xpc, $path);
1366  if (count($res->nodeset) > 0)
1367  {
1368  $cont_node = $res->nodeset[0]->parent_node();
1369  $par = new ilPCParagraph($this);
1370  $par->setNode($cont_node);
1371  return $par->getText();
1372  }
1373  }
1374  return "";
1375  }
1376 
1383  function setParagraphContent($a_hier_id, $a_content)
1384  {
1385  $node = $this->getContentNode($a_hier_id);
1386  if (is_object($node))
1387  {
1388  $node->set_content($a_content);
1389  }
1390  }
1391 
1392 // @todo end
1393 
1394 
1403  // @todo: can we do this better
1404  function setContainsIntLink($a_contains_link)
1405  {
1406  $this->contains_int_link = $a_contains_link;
1407  }
1408 
1413  // @todo: can we do this better
1414  function containsIntLink()
1415  {
1416  return $this->contains_int_link;
1417  }
1418 
1424  function setImportMode($a_val)
1425  {
1426  $this->import_mode = $a_val;
1427  }
1428 
1434  function getImportMode()
1435  {
1436  return $this->import_mode;
1437  }
1438 
1439  function needsImportParsing($a_parse = "")
1440  {
1441 
1442  if ($a_parse === true)
1443  {
1444  $this->needs_parsing = true;
1445  }
1446  if ($a_parse === false)
1447  {
1448  $this->needs_parsing = false;
1449  }
1450  return $this->needs_parsing;
1451  }
1452 
1458  // @todo: can we do this better
1459  public function setContainsQuestion($a_val)
1460  {
1461  $this->contains_question = $a_val;
1462  }
1463 
1469  public function getContainsQuestion()
1470  {
1471  return $this->contains_question;
1472  }
1473 
1474 
1479  // @todo: move to media class
1480  function collectMediaObjects($a_inline_only = true)
1481  {
1482 //echo htmlentities($this->getXMLFromDom());
1483  // determine all media aliases of the page
1484  $xpc = xpath_new_context($this->dom);
1485  $path = "//MediaObject/MediaAlias";
1486  $res = xpath_eval($xpc, $path);
1487  $mob_ids = array();
1488  for($i = 0; $i < count($res->nodeset); $i++)
1489  {
1490  $id_arr = explode("_", $res->nodeset[$i]->get_attribute("OriginId"));
1491  $mob_id = $id_arr[count($id_arr) - 1];
1492  $mob_ids[$mob_id] = $mob_id;
1493  }
1494 
1495  // determine all media aliases of interactive images
1496  $xpc = xpath_new_context($this->dom);
1497  $path = "//InteractiveImage/MediaAlias";
1498  $res = xpath_eval($xpc, $path);
1499  for($i = 0; $i < count($res->nodeset); $i++)
1500  {
1501  $id_arr = explode("_", $res->nodeset[$i]->get_attribute("OriginId"));
1502  $mob_id = $id_arr[count($id_arr) - 1];
1503  $mob_ids[$mob_id] = $mob_id;
1504  }
1505 
1506  // determine all inline internal media links
1507  $xpc = xpath_new_context($this->dom);
1508  $path = "//IntLink[@Type = 'MediaObject']";
1509  $res = xpath_eval($xpc, $path);
1510 
1511  for($i = 0; $i < count($res->nodeset); $i++)
1512  {
1513  if (($res->nodeset[$i]->get_attribute("TargetFrame") == "") ||
1514  (!$a_inline_only))
1515  {
1516  $target = $res->nodeset[$i]->get_attribute("Target");
1517  $id_arr = explode("_", $target);
1518  if (($id_arr[1] == IL_INST_ID) ||
1519  (substr($target, 0, 4) == "il__"))
1520  {
1521  $mob_id = $id_arr[count($id_arr) - 1];
1522  if (ilObject::_exists($mob_id))
1523  {
1524  $mob_ids[$mob_id] = $mob_id;
1525  }
1526  }
1527  }
1528  }
1529 
1530  return $mob_ids;
1531  }
1532 
1533 
1537  // @todo: can we do this better?
1538  function getInternalLinks($a_cnt_multiple = false)
1539  {
1540  // get all internal links of the page
1541  $xpc = xpath_new_context($this->dom);
1542  $path = "//IntLink";
1543  $res = xpath_eval($xpc, $path);
1544 
1545  $links = array();
1546  $cnt_multiple = 1;
1547  for($i = 0; $i < count($res->nodeset); $i++)
1548  {
1549  $add = "";
1550  if ($a_cnt_multiple)
1551  {
1552  $add = ":".$cnt_multiple;
1553  }
1554  $target = $res->nodeset[$i]->get_attribute("Target");
1555  $type = $res->nodeset[$i]->get_attribute("Type");
1556  $targetframe = $res->nodeset[$i]->get_attribute("TargetFrame");
1557  $anchor = $res->nodeset[$i]->get_attribute("Anchor");
1558  $links[$target.":".$type.":".$targetframe.":".$anchor.$add] =
1559  array("Target" => $target, "Type" => $type,
1560  "TargetFrame" => $targetframe, "Anchor" => $anchor);
1561 
1562  // get links (image map areas) for inline media objects
1563  if ($type == "MediaObject" && $targetframe == "")
1564  {
1565  if (substr($target, 0, 4) =="il__")
1566  {
1567  $id_arr = explode("_", $target);
1568  $id = $id_arr[count($id_arr) - 1];
1569 
1570  $med_links = ilMediaItem::_getMapAreasIntLinks($id);
1571  foreach($med_links as $key => $med_link)
1572  {
1573  $links[$key] = $med_link;
1574  }
1575  }
1576 
1577  }
1578 //echo "<br>-:".$target.":".$type.":".$targetframe.":-";
1579  $cnt_multiple++;
1580  }
1581  unset($xpc);
1582 
1583  // get all media aliases
1584  $xpc = xpath_new_context($this->dom);
1585  $path = "//MediaAlias";
1586  $res = xpath_eval($xpc, $path);
1587 
1588  require_once("Services/MediaObjects/classes/class.ilMediaItem.php");
1589  for($i = 0; $i < count($res->nodeset); $i++)
1590  {
1591  $oid = $res->nodeset[$i]->get_attribute("OriginId");
1592  if (substr($oid, 0, 4) =="il__")
1593  {
1594  $id_arr = explode("_", $oid);
1595  $id = $id_arr[count($id_arr) - 1];
1596 
1597  $med_links = ilMediaItem::_getMapAreasIntLinks($id);
1598  foreach($med_links as $key => $med_link)
1599  {
1600  $links[$key] = $med_link;
1601  }
1602  }
1603  }
1604  unset($xpc);
1605 
1606  return $links;
1607  }
1608 
1613  // @todo: move to media class
1614  function getMultimediaXML()
1615  {
1616  $mob_ids = $this->collectMediaObjects();
1617 
1618  // get xml of corresponding media objects
1619  $mobs_xml = "";
1620  require_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
1621  foreach($mob_ids as $mob_id => $dummy)
1622  {
1623  if (ilObject::_lookupType($mob_id) == "mob")
1624  {
1625  $mob_obj = new ilObjMediaObject($mob_id);
1626  $mobs_xml .= $mob_obj->getXML(IL_MODE_OUTPUT);
1627  }
1628  }
1629 //var_dump($mobs_xml);
1630  return $mobs_xml;
1631  }
1632 
1636  // @todo: move to media class
1637  function getMediaAliasElement($a_mob_id, $a_nr = 1)
1638  {
1639  $xpc = xpath_new_context($this->dom);
1640  $path = "//MediaObject/MediaAlias[@OriginId='il__mob_$a_mob_id']";
1641  $res = xpath_eval($xpc, $path);
1642  $mal_node = $res->nodeset[$a_nr - 1];
1643  $mob_node = $mal_node->parent_node();
1644 
1645  return $this->dom->dump_node($mob_node);
1646  }
1647 
1653  function validateDom()
1654  {
1655  $this->stripHierIDs();
1656 
1657  // possible fix for #14820
1658  libxml_disable_entity_loader(false);
1659 
1660  @$this->dom->validate($error);
1661  //var_dump($this->dom); exit;
1662  return $error;
1663  }
1664 
1680  // @todo: can we do this better? remove dependencies?
1681  function addHierIDs()
1682  {
1683  $this->hier_ids = array();
1684  $this->first_row_ids = array();
1685  $this->first_col_ids = array();
1686  $this->list_item_ids = array();
1687  $this->file_item_ids = array();
1688 
1689  // set hierarchical ids for Paragraphs, Tables, TableRows and TableData elements
1690  $xpc = xpath_new_context($this->dom);
1691  //$path = "//Paragraph | //Table | //TableRow | //TableData";
1692 
1693  $sep = $path = "";
1694  foreach ($this->id_elements as $el)
1695  {
1696  $path.= $sep."//".$el;
1697  $sep = " | ";
1698  }
1699 
1700  $res = xpath_eval($xpc, $path);
1701  for($i = 0; $i < count($res->nodeset); $i++)
1702  {
1703  $cnode = $res->nodeset[$i];
1704  $ctag = $cnode->node_name();
1705 
1706  // get hierarchical id of previous sibling
1707  $sib_hier_id = "";
1708  while($cnode = $cnode->previous_sibling())
1709  {
1710  if (($cnode->node_type() == XML_ELEMENT_NODE)
1711  && $cnode->has_attribute("HierId"))
1712  {
1713  $sib_hier_id = $cnode->get_attribute("HierId");
1714  //$sib_hier_id = $id_attr->value();
1715  break;
1716  }
1717  }
1718 
1719  if ($sib_hier_id != "") // set id to sibling id "+ 1"
1720  {
1721  require_once("./Services/COPage/classes/class.ilPageContent.php");
1722  $node_hier_id = ilPageContent::incEdId($sib_hier_id);
1723  $res->nodeset[$i]->set_attribute("HierId", $node_hier_id);
1724  $this->hier_ids[] = $node_hier_id;
1725  if ($ctag == "TableData")
1726  {
1727  if (substr($par_hier_id,strlen($par_hier_id)-2) == "_1")
1728  {
1729  $this->first_row_ids[] = $node_hier_id;
1730  }
1731  }
1732  if ($ctag == "ListItem")
1733  {
1734  $this->list_item_ids[] = $node_hier_id;
1735  }
1736  if ($ctag == "FileItem")
1737  {
1738  $this->file_item_ids[] = $node_hier_id;
1739  }
1740  }
1741  else // no sibling -> node is first child
1742  {
1743  // get hierarchical id of next parent
1744  $cnode = $res->nodeset[$i];
1745  $par_hier_id = "";
1746  while($cnode = $cnode->parent_node())
1747  {
1748  if (($cnode->node_type() == XML_ELEMENT_NODE)
1749  && $cnode->has_attribute("HierId"))
1750  {
1751  $par_hier_id = $cnode->get_attribute("HierId");
1752  //$par_hier_id = $id_attr->value();
1753  break;
1754  }
1755  }
1756 //echo "<br>par:".$par_hier_id." ($ctag)";
1757  if (($par_hier_id != "") && ($par_hier_id != "pg")) // set id to parent_id."_1"
1758  {
1759  $node_hier_id = $par_hier_id."_1";
1760  $res->nodeset[$i]->set_attribute("HierId", $node_hier_id);
1761  $this->hier_ids[] = $node_hier_id;
1762  if ($ctag == "TableData")
1763  {
1764  $this->first_col_ids[] = $node_hier_id;
1765  if (substr($par_hier_id,strlen($par_hier_id)-2) == "_1")
1766  {
1767  $this->first_row_ids[] = $node_hier_id;
1768  }
1769  }
1770  if ($ctag == "ListItem")
1771  {
1772  $this->list_item_ids[] = $node_hier_id;
1773  }
1774  if ($ctag == "FileItem")
1775  {
1776  $this->file_item_ids[] = $node_hier_id;
1777  }
1778 
1779  }
1780  else // no sibling, no parent -> first node
1781  {
1782  $node_hier_id = "1";
1783  $res->nodeset[$i]->set_attribute("HierId", $node_hier_id);
1784  $this->hier_ids[] = $node_hier_id;
1785  }
1786  }
1787  }
1788 
1789  // set special hierarchical id "pg" for pageobject
1790  $xpc = xpath_new_context($this->dom);
1791  $path = "//PageObject";
1792  $res = xpath_eval($xpc, $path);
1793  for($i = 0; $i < count($res->nodeset); $i++) // should only be 1
1794  {
1795  $res->nodeset[$i]->set_attribute("HierId", "pg");
1796  $this->hier_ids[] = "pg";
1797  }
1798  unset($xpc);
1799  }
1800 
1804  function getHierIds()
1805  {
1806  return $this->hier_ids;
1807  }
1808 
1812  // @todo: move to table classes
1813  function getFirstRowIds()
1814  {
1815  return $this->first_row_ids;
1816  }
1817 
1821  // @todo: move to table classes
1823  {
1824  return $this->first_col_ids;
1825  }
1826 
1830  // @todo: move to list class
1831  function getListItemIds()
1832  {
1833  return $this->list_item_ids;
1834  }
1835 
1839  // @todo: move to file item class
1840  function getFileItemIds()
1841  {
1842  return $this->file_item_ids;
1843  }
1844 
1848  function stripHierIDs()
1849  {
1850  if(is_object($this->dom))
1851  {
1852  $xpc = xpath_new_context($this->dom);
1853  $path = "//*[@HierId]";
1854  $res = xpath_eval($xpc, $path);
1855  for($i = 0; $i < count($res->nodeset); $i++) // should only be 1
1856  {
1857  if ($res->nodeset[$i]->has_attribute("HierId"))
1858  {
1859  $res->nodeset[$i]->remove_attribute("HierId");
1860  }
1861  }
1862  unset($xpc);
1863  }
1864  }
1865 
1869  function getHierIdsForPCIds($a_pc_ids)
1870  {
1871  if (!is_array($a_pc_ids) || count($a_pc_ids) == 0)
1872  {
1873  return array();
1874  }
1875  $ret = array();
1876 
1877  if(is_object($this->dom))
1878  {
1879  $xpc = xpath_new_context($this->dom);
1880  $path = "//*[@PCID]";
1881  $res = xpath_eval($xpc, $path);
1882  for($i = 0; $i < count($res->nodeset); $i++) // should only be 1
1883  {
1884  $pc_id = $res->nodeset[$i]->get_attribute("PCID");
1885  if (in_array($pc_id, $a_pc_ids))
1886  {
1887  $ret[$pc_id] = $res->nodeset[$i]->get_attribute("HierId");
1888  }
1889  }
1890  unset($xpc);
1891  }
1892 //var_dump($ret);
1893  return $ret;
1894  }
1895 
1899  // @todo: move to file item class
1900  function addFileSizes()
1901  {
1902  $xpc = xpath_new_context($this->dom);
1903  $path = "//FileItem";
1904  $res = xpath_eval($xpc, $path);
1905  for($i = 0; $i < count($res->nodeset); $i++)
1906  {
1907  $cnode = $res->nodeset[$i];
1908  $size_node = $this->dom->create_element("Size");
1909  $size_node = $cnode->append_child($size_node);
1910 
1911  $childs = $cnode->child_nodes();
1912  $size = "";
1913  for($j = 0; $j < count($childs); $j++)
1914  {
1915  if ($childs[$j]->node_name() == "Identifier")
1916  {
1917  if ($childs[$j]->has_attribute("Entry"))
1918  {
1919  $entry = $childs[$j]->get_attribute("Entry");
1920  $entry_arr = explode("_", $entry);
1921  $id = $entry_arr[count($entry_arr) - 1];
1922  require_once("./Modules/File/classes/class.ilObjFile.php");
1924  }
1925  }
1926  }
1927  $size_node->set_content($size);
1928  }
1929 
1930  unset($xpc);
1931  }
1932 
1937  // @todo: possible to improve this?
1938  function resolveIntLinks($a_link_map = null)
1939  {
1940  $changed = false;
1941 
1942  $this->log->debug("start");
1943 
1944  // resolve normal internal links
1945  $xpc = xpath_new_context($this->dom);
1946  $path = "//IntLink";
1947  $res = xpath_eval($xpc, $path);
1948  for($i = 0; $i < count($res->nodeset); $i++)
1949  {
1950  $target = $res->nodeset[$i]->get_attribute("Target");
1951  $type = $res->nodeset[$i]->get_attribute("Type");
1952 
1953  if ($a_link_map == null)
1954  {
1955  $new_target = ilInternalLink::_getIdForImportId($type, $target);
1956  $this->log->debug("no map, type: ".$type.", target: ".$target.", new target: ".$new_target);
1957 // echo "-".$new_target."-".$type."-".$target."-"; exit;
1958  }
1959  else
1960  {
1961  $nt = explode("_", $a_link_map[$target]);
1962  $new_target = false;
1963  if ($nt[1] == IL_INST_ID)
1964  {
1965  $new_target = "il__".$nt[2]."_".$nt[3];
1966  }
1967  $this->log->debug("map, type: ".$type.", target: ".$target.", new target: ".$new_target);
1968  }
1969  if ($new_target !== false)
1970  {
1971  $res->nodeset[$i]->set_attribute("Target", $new_target);
1972  $changed = true;
1973  }
1974  else // check wether link target is same installation
1975  {
1976  if (ilInternalLink::_extractInstOfTarget($target) == IL_INST_ID &&
1977  IL_INST_ID > 0 && $type != "RepositoryItem")
1978  {
1980  if (ilInternalLink::_exists($type, $new_target))
1981  {
1982  $res->nodeset[$i]->set_attribute("Target", $new_target);
1983  $changed = true;
1984  }
1985  }
1986  }
1987 
1988  }
1989  unset($xpc);
1990 
1991  // resolve internal links in map areas
1992  $xpc = xpath_new_context($this->dom);
1993  $path = "//MediaAlias";
1994  $res = xpath_eval($xpc, $path);
1995 //echo "<br><b>page::resolve</b><br>";
1996 //echo "Content:".htmlentities($this->getXMLFromDOM()).":<br>";
1997  for($i = 0; $i < count($res->nodeset); $i++)
1998  {
1999  $orig_id = $res->nodeset[$i]->get_attribute("OriginId");
2000  $id_arr = explode("_", $orig_id);
2001  $mob_id = $id_arr[count($id_arr) - 1];
2003  }
2004  return $changed;
2005  }
2006 
2013  // @todo: move to media classes?
2014  function resolveMediaAliases($a_mapping, $a_reuse_existing_by_import = false)
2015  {
2016  // resolve normal internal links
2017  $xpc = xpath_new_context($this->dom);
2018  $path = "//MediaAlias";
2019  $res = xpath_eval($xpc, $path);
2020  $changed = false;
2021  for($i = 0; $i < count($res->nodeset); $i++)
2022  {
2023  // get the ID of the import file from the xml
2024  $old_id = $res->nodeset[$i]->get_attribute("OriginId");
2025  $old_id = explode("_", $old_id);
2026  $old_id = $old_id[count($old_id) - 1];
2027  // get the new id from the current mapping
2028  if ($a_mapping[$old_id] > 0)
2029  {
2030  $new_id = $a_mapping[$old_id];
2031  if ($a_reuse_existing_by_import)
2032  {
2033  // this should work, if the lm has been imported in a translation installation and re-exported
2034  $import_id = ilObject::_lookupImportId($new_id);
2035  $imp = explode("_", $import_id);
2036  if ($imp[1] == IL_INST_ID && $imp[2] == "mob" && ilObject::_lookupType($imp[3]) == "mob")
2037  {
2038  $new_id = $imp[3];
2039  }
2040 
2041  // now check, if the translation has been done just by changing text in the exported
2042  // translation file
2043  if ($import_id == "")
2044  {
2045  // if the old_id is also referred by the page content of the default language
2046  // we assume that this media object is unchanged
2047  include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
2048  $med_of_def_lang = ilObjMediaObject::_getMobsOfObject("lm:pg", $this->getId(), 0, "-");
2049  if (in_array($old_id, $med_of_def_lang))
2050  {
2051  $new_id = $old_id;
2052  }
2053  }
2054  }
2055 
2056  $res->nodeset[$i]->set_attribute("OriginId", "il__mob_".$new_id);
2057  $changed = true;
2058  }
2059  }
2060  unset($xpc);
2061 
2062  return $changed;
2063  }
2064 
2071  // @todo: move to iim classes?
2072  function resolveIIMMediaAliases($a_mapping)
2073  {
2074  // resolve normal internal links
2075  $xpc = xpath_new_context($this->dom);
2076  $path = "//InteractiveImage/MediaAlias";
2077  $res = xpath_eval($xpc, $path);
2078  $changed = false;
2079  for($i = 0; $i < count($res->nodeset); $i++)
2080  {
2081  $old_id = $res->nodeset[$i]->get_attribute("OriginId");
2082  if ($a_mapping[$old_id] > 0)
2083  {
2084  $res->nodeset[$i]->set_attribute("OriginId", "il__mob_".$a_mapping[$old_id]);
2085  $changed = true;
2086  }
2087  }
2088  unset($xpc);
2089 
2090  return $changed;
2091  }
2092 
2099  // @todo: move to file classes?
2100  function resolveFileItems($a_mapping)
2101  {
2102  // resolve normal internal links
2103  $xpc = xpath_new_context($this->dom);
2104  $path = "//FileItem/Identifier";
2105  $res = xpath_eval($xpc, $path);
2106  $changed = false;
2107  for($i = 0; $i < count($res->nodeset); $i++)
2108  {
2109  $old_id = $res->nodeset[$i]->get_attribute("Entry");
2110  $old_id = explode("_", $old_id);
2111  $old_id = $old_id[count($old_id) - 1];
2112  if ($a_mapping[$old_id] > 0)
2113  {
2114  $res->nodeset[$i]->set_attribute("Entry", "il__file_".$a_mapping[$old_id]);
2115  $changed = true;
2116  }
2117  }
2118  unset($xpc);
2119 
2120  return $changed;
2121  }
2122 
2127  // @todo: move to question classes
2128  function resolveQuestionReferences($a_mapping)
2129  {
2130  // resolve normal internal links
2131  $xpc = xpath_new_context($this->dom);
2132  $path = "//Question";
2133  $res = xpath_eval($xpc, $path);
2134  $updated = false;
2135  for($i = 0; $i < count($res->nodeset); $i++)
2136  {
2137  $qref = $res->nodeset[$i]->get_attribute("QRef");
2138 
2139  if (isset($a_mapping[$qref]))
2140  {
2141  $res->nodeset[$i]->set_attribute("QRef", "il__qst_".$a_mapping[$qref]["pool"]);
2142  $updated = true;
2143  }
2144  }
2145  unset($xpc);
2146 
2147  return $updated;
2148  }
2149 
2150 
2157  // @todo: generalize, internal links usage info
2158  function moveIntLinks($a_from_to)
2159  {
2160  $this->buildDom();
2161 
2162  $changed = false;
2163 
2164  // resolve normal internal links
2165  $xpc = xpath_new_context($this->dom);
2166  $path = "//IntLink";
2167  $res = xpath_eval($xpc, $path);
2168  for($i = 0; $i < count($res->nodeset); $i++)
2169  {
2170  $target = $res->nodeset[$i]->get_attribute("Target");
2171  $type = $res->nodeset[$i]->get_attribute("Type");
2173  if ($a_from_to[$obj_id] > 0 && is_int(strpos($target, "__")))
2174  {
2175  if ($type == "PageObject" && ilLMObject::_lookupType($a_from_to[$obj_id]) == "pg")
2176  {
2177  $res->nodeset[$i]->set_attribute("Target", "il__pg_".$a_from_to[$obj_id]);
2178  $changed = true;
2179  }
2180  if ($type == "StructureObject" && ilLMObject::_lookupType($a_from_to[$obj_id]) == "st")
2181  {
2182  $res->nodeset[$i]->set_attribute("Target", "il__st_".$a_from_to[$obj_id]);
2183  $changed = true;
2184  }
2185  }
2186  }
2187  unset($xpc);
2188 
2189  // map areas
2190  $this->addHierIDs();
2191  $xpc = xpath_new_context($this->dom);
2192  $path = "//MediaAlias";
2193  $res = xpath_eval($xpc, $path);
2194 
2195  require_once("Services/MediaObjects/classes/class.ilMediaItem.php");
2196  require_once("Services/COPage/classes/class.ilMediaAliasItem.php");
2197 
2198  for($i = 0; $i < count($res->nodeset); $i++)
2199  {
2200  $media_object_node = $res->nodeset[$i]->parent_node();
2201  $page_content_node = $media_object_node->parent_node();
2202  $c_hier_id = $page_content_node->get_attribute("HierId");
2203 
2204  // first check, wheter we got instance map areas -> take these
2205  $std_alias_item = new ilMediaAliasItem($this->dom,
2206  $c_hier_id, "Standard");
2207  $areas = $std_alias_item->getMapAreas();
2208  $correction_needed = false;
2209  if (count($areas) > 0)
2210  {
2211  // check if correction needed
2212  foreach($areas as $area)
2213  {
2214  if ($area["Type"] == "PageObject" ||
2215  $area["Type"] == "StructureObject")
2216  {
2217  $t = $area["Target"];
2218  $tid = _extractObjIdOfTarget($t);
2219  if ($a_from_to[$tid] > 0)
2220  {
2221  $correction_needed = true;
2222  }
2223  }
2224  }
2225  }
2226  else
2227  {
2228  $areas = array();
2229 
2230  // get object map areas and check whether at least one must
2231  // be corrected
2232  $oid = $res->nodeset[$i]->get_attribute("OriginId");
2233  if (substr($oid, 0, 4) =="il__")
2234  {
2235  $id_arr = explode("_", $oid);
2236  $id = $id_arr[count($id_arr) - 1];
2237 
2238  $mob = new ilObjMediaObject($id);
2239  $med_item = $mob->getMediaItem("Standard");
2240  $med_areas = $med_item->getMapAreas();
2241 
2242  foreach($med_areas as $area)
2243  {
2244  $link_type = ($area->getLinkType() == "int")
2245  ? "IntLink"
2246  : "ExtLink";
2247 
2248  $areas[] = array(
2249  "Nr" => $area->getNr(),
2250  "Shape" => $area->getShape(),
2251  "Coords" => $area->getCoords(),
2252  "Link" => array(
2253  "LinkType" => $link_type,
2254  "Href" => $area->getHref(),
2255  "Title" => $area->getTitle(),
2256  "Target" => $area->getTarget(),
2257  "Type" => $area->getType(),
2258  "TargetFrame" => $area->getTargetFrame()
2259  )
2260  );
2261 
2262  if ($area->getType() == "PageObject" ||
2263  $area->getType() == "StructureObject")
2264  {
2265  $t = $area->getTarget();
2267  if ($a_from_to[$tid] > 0)
2268  {
2269  $correction_needed = true;
2270  }
2271 //var_dump($a_from_to);
2272  }
2273  }
2274  }
2275  }
2276 
2277  // correct map area links
2278  if ($correction_needed)
2279  {
2280  $changed = true;
2281  $std_alias_item->deleteAllMapAreas();
2282  foreach($areas as $area)
2283  {
2284  if ($area["Link"]["LinkType"] == "IntLink")
2285  {
2286  $target = $area["Link"]["Target"];
2287  $type = $area["Link"]["Type"];
2289  if ($a_from_to[$obj_id] > 0)
2290  {
2291  if ($type == "PageObject" && ilLMObject::_lookupType($a_from_to[$obj_id]) == "pg")
2292  {
2293  $area["Link"]["Target"] = "il__pg_".$a_from_to[$obj_id];
2294  }
2295  if ($type == "StructureObject" && ilLMObject::_lookupType($a_from_to[$obj_id]) == "st")
2296  {
2297  $area["Link"]["Target"] = "il__st_".$a_from_to[$obj_id];
2298  }
2299  }
2300  }
2301 
2302  $std_alias_item->addMapArea($area["Shape"], $area["Coords"],
2303  $area["Link"]["Title"],
2304  array( "Type" => $area["Link"]["Type"],
2305  "TargetFrame" => $area["Link"]["TargetFrame"],
2306  "Target" => $area["Link"]["Target"],
2307  "Href" => $area["Link"]["Href"],
2308  "LinkType" => $area["Link"]["LinkType"],
2309  ));
2310  }
2311  }
2312  }
2313  unset($xpc);
2314 
2315  return $changed;
2316  }
2317 
2323  // @todo: generalize, internal links usage info
2324  static function _handleImportRepositoryLinks($a_rep_import_id, $a_rep_type, $a_rep_ref_id)
2325  {
2326  include_once("./Services/Link/classes/class.ilInternalLink.php");
2327 
2328 //echo "-".$a_rep_import_id."-".$a_rep_ref_id."-";
2329  $sources = ilInternalLink::_getSourcesOfTarget("obj",
2330  ilInternalLink::_extractObjIdOfTarget($a_rep_import_id),
2331  ilInternalLink::_extractInstOfTarget($a_rep_import_id));
2332 //var_dump($sources);
2333  foreach($sources as $source)
2334  {
2335 //echo "A";
2336  if ($source["type"] == "lm:pg")
2337  {
2338 //echo "B";
2339  include_once("./Modules/LearningModule/classes/class.ilLMPage.php");
2340  if (self::_exists("lm", $source["id"], $source["lang"]))
2341  {
2342  $page_obj = new ilLMPage($source["id"], 0, $source["lang"]);
2343  if (!$page_obj->page_not_found)
2344  {
2345  //echo "C";
2346  $page_obj->handleImportRepositoryLink($a_rep_import_id,
2347  $a_rep_type, $a_rep_ref_id);
2348  }
2349  $page_obj->update();
2350  }
2351  }
2352  }
2353  }
2354 
2355  // @todo: generalize, internal links usage info
2356  function handleImportRepositoryLink($a_rep_import_id, $a_rep_type, $a_rep_ref_id)
2357  {
2358  $this->buildDom();
2359 
2360  // resolve normal internal links
2361  $xpc = xpath_new_context($this->dom);
2362  $path = "//IntLink";
2363  $res = xpath_eval($xpc, $path);
2364 //echo "1";
2365  for($i = 0; $i < count($res->nodeset); $i++)
2366  {
2367 //echo "2";
2368  $target = $res->nodeset[$i]->get_attribute("Target");
2369  $type = $res->nodeset[$i]->get_attribute("Type");
2370  if ($target == $a_rep_import_id && $type == "RepositoryItem")
2371  {
2372 //echo "setting:"."il__".$a_rep_type."_".$a_rep_ref_id;
2373  $res->nodeset[$i]->set_attribute("Target",
2374  "il__".$a_rep_type."_".$a_rep_ref_id);
2375  }
2376  }
2377  unset($xpc);
2378  }
2379 
2386  function handleRepositoryLinksOnCopy($a_mapping, $a_source_ref_id)
2387  {
2388  global $tree;
2389 
2390  $this->buildDom();
2391  $this->log->debug("Handle repository links...");
2392 
2393  // resolve normal internal links
2394  $xpc = xpath_new_context($this->dom);
2395  $path = "//IntLink";
2396  $res = xpath_eval($xpc, $path);
2397  for($i = 0; $i < count($res->nodeset); $i++)
2398  {
2399  $target = $res->nodeset[$i]->get_attribute("Target");
2400  $type = $res->nodeset[$i]->get_attribute("Type");
2401  $this->log->debug("Target: ".$target);
2402  $t = explode("_", $target);
2403  if ($type == "RepositoryItem" && ((int) $t[1] == 0 || (int) $t[1] == IL_INST_ID))
2404  {
2405  if (isset($a_mapping[$t[3]]))
2406  {
2407  // we have a mapping -> replace the ID
2408  $this->log->debug("... replace " . $t[3] . " with " . $a_mapping[$t[3]] . ".");
2409  $res->nodeset[$i]->set_attribute("Target",
2410  "il__obj_" . $a_mapping[$t[3]]);
2411  }
2412  else if ($tree->isGrandChild($a_source_ref_id, $t[3]))
2413  {
2414  // we have no mapping, but the linked object is child of the original node -> remove link
2415  $this->log->debug("... remove links.");
2416  if ($res->nodeset[$i]->parent_node()->node_name() == "MapArea") // simply remove map areas
2417  {
2418  $parent = $res->nodeset[$i]->parent_node();
2419  $parent->unlink_node($parent);
2420  }
2421  else // replace link by content of the link for other internal links
2422  {
2423  $source_node = $res->nodeset[$i];
2424  $new_node = $source_node->clone_node(true);
2425  $new_node->unlink_node($new_node);
2426  $childs = $new_node->child_nodes();
2427  for ($j = 0; $j < count($childs); $j++)
2428  {
2429  $this->log->debug("... move node $j " . $childs[$j]->node_name() . " before " . $source_node->node_name());
2430  $source_node->insert_before($childs[$j], $source_node);
2431  }
2432  $source_node->unlink_node($source_node);
2433  }
2434  }
2435  }
2436  }
2437  unset($xpc);
2438  }
2439 
2440 
2444  function createFromXML()
2445  {
2446  global $lng, $ilDB, $ilUser;
2447 
2448 //echo "<br>PageObject::createFromXML[".$this->getId()."]";
2449 
2450  $empty = false;
2451  if($this->getXMLContent() == "")
2452  {
2453  $this->setXMLContent("<PageObject></PageObject>");
2454  $empty = true;
2455  }
2456 
2457  $content = $this->getXMLContent();
2458  $this->buildDom(true);
2459  $dom_doc = $this->getDomDoc();
2460 
2461  $iel = $this->containsDeactivatedElements($content);
2462  $inl = $this->containsIntLinks($content);
2463 
2464  // create object
2465  $ilDB->insert("page_object", array(
2466  "page_id" => array("integer", $this->getId()),
2467  "parent_id" => array("integer", $this->getParentId()),
2468  "lang" => array("text", $this->getLanguage()),
2469  "content" => array("clob", $content),
2470  "parent_type" => array("text", $this->getParentType()),
2471  "create_user" => array("integer", $ilUser->getId()),
2472  "last_change_user" => array("integer", $ilUser->getId()),
2473  "active" => array("integer", (int) $this->getActive()),
2474  "activation_start" => array("timestamp", $this->getActivationStart()),
2475  "activation_end" => array("timestamp", $this->getActivationEnd()),
2476  "show_activation_info" => array("integer", (int) $this->getShowActivationInfo()),
2477  "inactive_elements" => array("integer", $iel),
2478  "int_links" => array("integer", $inl),
2479  "created" => array("timestamp", ilUtil::now()),
2480  "last_change" => array("timestamp", ilUtil::now())
2481  ));
2482 
2483  // after update event
2484  $this->__afterUpdate($dom_doc, $content, true, $empty);
2485 
2486  }
2487 
2488 
2497  function updateFromXML()
2498  {
2499  global $lng, $ilDB, $ilUser;
2500 
2501  $this->log->debug("ilPageObject, updateFromXML(): start, id: ".$this->getId());
2502 
2503 //echo "<br>PageObject::updateFromXML[".$this->getId()."]";
2504 //echo "update:".ilUtil::prepareDBString(($this->getXMLContent())).":<br>";
2505 //echo "update:".htmlentities($this->getXMLContent()).":<br>";
2506 
2507  $content = $this->getXMLContent();
2508 
2509  $this->log->debug("ilPageObject, updateFromXML(): content: ".substr($content, 0, 100));
2510 
2511  $this->buildDom(true);
2512  $dom_doc = $this->getDomDoc();
2513 
2514  $iel = $this->containsDeactivatedElements($content);
2515  $inl = $this->containsIntLinks($content);
2516 
2517  $ilDB->update("page_object", array(
2518  "content" => array("clob", $content),
2519  "parent_id" => array("integer", $this->getParentId()),
2520  "last_change_user" => array("integer", $ilUser->getId()),
2521  "last_change" => array("timestamp", ilUtil::now()),
2522  "active" => array("integer", $this->getActive()),
2523  "activation_start" => array("timestamp", $this->getActivationStart()),
2524  "activation_end" => array("timestamp", $this->getActivationEnd()),
2525  "inactive_elements" => array("integer", $iel),
2526  "int_links" => array("integer", $inl),
2527  ), array(
2528  "page_id" => array("integer", $this->getId()),
2529  "parent_type" => array("text", $this->getParentType()),
2530  "lang" => array("text", $this->getLanguage())
2531  ));
2532 
2533  // after update event
2534  $this->__afterUpdate($dom_doc, $content);
2535 
2536  $this->log->debug("ilPageObject, updateFromXML(): end");
2537 
2538  return true;
2539  }
2540 
2547  protected final function __afterUpdate($a_domdoc, $a_xml, $a_creation = false, $a_empty = false)
2548  {
2549  // we do not need this if we are creating an empty page
2550  if (!$a_creation || !$a_empty)
2551  {
2552  // save internal link information
2553  // the page object is responsible to do this, since it "offers" the
2554  // internal link feature pc and page classes
2555  $this->saveInternalLinks($a_domdoc);
2556 
2557  // save style usage
2558  $this->saveStyleUsage($a_domdoc);
2559 
2560  // pc classes hook
2561  include_once("./Services/COPage/classes/class.ilCOPagePCDef.php");
2563  foreach ($defs as $def)
2564  {
2566  $cl = $def["pc_class"];
2567  call_user_func($def["pc_class"].'::afterPageUpdate', $this, $a_domdoc, $a_xml, $a_creation);
2568  }
2569  }
2570 
2571  // call page hook
2572  $this->afterUpdate($a_domdoc, $a_xml);
2573 
2574  // call update listeners
2575  $this->callUpdateListeners();
2576  }
2577 
2584  function afterUpdate()
2585  {
2586  }
2587 
2588 
2593  function update($a_validate = true, $a_no_history = false)
2594  {
2595  global $lng, $ilDB, $ilUser, $ilLog, $ilCtrl;
2596 
2597  $this->log->debug("ilPageObject, update(): start, id: ".$this->getId());
2598 
2599  $lm_set = new ilSetting("lm");
2600 
2601 //echo "<br>**".$this->getId()."**";
2602 //echo "<br>PageObject::update[".$this->getId()."],validate($a_validate)";
2603 //echo "\n<br>dump_all2:".$this->dom->dump_mem(0, "UTF-8").":";
2604 //echo "\n<br>PageObject::update:".$this->getXMLFromDom().":";
2605 //debug_print_backtrace();
2606 //echo "<br>PageObject::update:".htmlentities($this->getXMLFromDom()); exit;
2607 
2608  // add missing pc ids
2609  if (!$this->checkPCIds())
2610  {
2611  $this->insertPCIds();
2612  }
2613 
2614  // test validating
2615  if($a_validate)
2616  {
2617  $errors = $this->validateDom();
2618  }
2619 //var_dump($errors); exit;
2620  if (empty($errors) && !$this->getEditLock())
2621  {
2622  include_once("./Services/User/classes/class.ilUserUtil.php");
2623  $lock = $this->getEditLockInfo();
2624  $errors[0] = array(0 => 0,
2625  1 => "nocontent#".$lng->txt("cont_not_saved_edit_lock_expired")."<br />".
2626  $lng->txt("obj_usr").": ".
2627  ilUserUtil::getNamePresentation($lock["edit_lock_user"])."<br />".
2628  $lng->txt("content_until").": ".
2629  ilDatePresentation::formatDate(new ilDateTime($lock["edit_lock_until"],IL_CAL_UNIX))
2630  );
2631  }
2632 
2633  if (!empty($errors))
2634  {
2635  $this->log->debug("ilPageObject, update(): errors: ".print_r($errors, true));
2636  }
2637 
2638 //echo "-".htmlentities($this->getXMLFromDom())."-"; exit;
2639  if(empty($errors))
2640  {
2641  // @todo 1: is this page type or pc content type
2642  // related -> plugins should be able to hook in!?
2644 
2645  // get xml content
2646  $content = $this->getXMLFromDom();
2647  $dom_doc = $this->getDomDoc();
2648 
2649  // this needs to be locked
2650 
2651  // write history entry
2652  $old_set = $ilDB->query("SELECT * FROM page_object WHERE ".
2653  "page_id = ".$ilDB->quote($this->getId(), "integer")." AND ".
2654  "parent_type = ".$ilDB->quote($this->getParentType(), "text")." AND ".
2655  "lang = ".$ilDB->quote($this->getLanguage(), "text"));
2656  $last_nr_set = $ilDB->query("SELECT max(nr) as mnr FROM page_history WHERE ".
2657  "page_id = ".$ilDB->quote($this->getId(), "integer")." AND ".
2658  "parent_type = ".$ilDB->quote($this->getParentType(), "text")." AND ".
2659  "lang = ".$ilDB->quote($this->getLanguage(), "text"));
2660  $last_nr = $ilDB->fetchAssoc($last_nr_set);
2661  if ($old_rec = $ilDB->fetchAssoc($old_set))
2662  {
2663  // only save, if something has changed
2664  // added user id to the check for ilias 5.0, 7.10.2014
2665  if (($content != $old_rec["content"] || $ilUser->getId() != $old_rec["last_change_user"]) &&
2666  !$a_no_history && !$this->history_saved && $lm_set->get("page_history", 1))
2667  {
2668  if ($old_rec["content"] != "<PageObject></PageObject>")
2669  {
2670  $ilDB->manipulateF("DELETE FROM page_history WHERE ".
2671  "page_id = %s AND parent_type = %s AND hdate = %s AND lang = %s",
2672  array("integer", "text", "timestamp", "text"),
2673  array($old_rec["page_id"], $old_rec["parent_type"], $old_rec["last_change"], $old_rec["lang"]));
2674 
2675  // the following lines are a workaround for
2676  // bug 6741
2677  $last_c = $old_rec["last_change"];
2678  if ($last_c == "")
2679  {
2680  $last_c = ilUtil::now();
2681  }
2682 
2683  $ilDB->insert("page_history", array(
2684  "page_id" => array("integer", $old_rec["page_id"]),
2685  "parent_type" => array("text", $old_rec["parent_type"]),
2686  "lang" => array("text", $old_rec["lang"]),
2687  "hdate" => array("timestamp", $last_c),
2688  "parent_id" => array("integer", $old_rec["parent_id"]),
2689  "content" => array("clob", $old_rec["content"]),
2690  "user_id" => array("integer", $old_rec["last_change_user"]),
2691  "ilias_version" => array("text", ILIAS_VERSION_NUMERIC),
2692  "nr" => array("integer", (int) $last_nr["mnr"] + 1)
2693  ));
2694 
2695  $old_content = $old_rec["content"];
2696  $old_domdoc = new DOMDocument();
2697  $old_nr = $last_nr["mnr"] + 1;
2698  $old_domdoc->loadXML('<?xml version="1.0" encoding="UTF-8"?>'.$old_content);
2699 
2700  // after history entry creation event
2701  $this->__afterHistoryEntry($old_domdoc, $old_content, $old_nr);
2702 
2703  $this->history_saved = true; // only save one time
2704  }
2705  else
2706  {
2707  $this->history_saved = true; // do not save on first change
2708  }
2709  }
2710  }
2711 //echo htmlentities($content);
2712  $em = (trim($content) == "<PageObject/>")
2713  ? 1
2714  : 0;
2715 
2716  // @todo: pass dom instead?
2717  $iel = $this->containsDeactivatedElements($content);
2718  $inl = $this->containsIntLinks($content);
2719 
2720  $ilDB->update("page_object", array(
2721  "content" => array("clob", $content),
2722  "parent_id" => array("integer", $this->getParentId()),
2723  "last_change_user" => array("integer", $ilUser->getId()),
2724  "last_change" => array("timestamp", ilUtil::now()),
2725  "is_empty" => array("integer", $em),
2726  "active" => array("integer", $this->getActive()),
2727  "activation_start" => array("timestamp", $this->getActivationStart()),
2728  "activation_end" => array("timestamp", $this->getActivationEnd()),
2729  "show_activation_info" => array("integer", $this->getShowActivationInfo()),
2730  "inactive_elements" => array("integer", $iel),
2731  "int_links" => array("integer", $inl),
2732  ), array(
2733  "page_id" => array("integer", $this->getId()),
2734  "parent_type" => array("text", $this->getParentType()),
2735  "lang" => array("text", $this->getLanguage())
2736  ));
2737 
2738  // after update event
2739  $this->__afterUpdate($dom_doc, $content);
2740 
2741  $this->log->debug("ilPageObject, update(): updated and returning true, content: ".substr($this->getXMLContent(), 0, 100));
2742 
2743 //echo "<br>PageObject::update:".htmlentities($this->getXMLContent()).":";
2744  return true;
2745  }
2746  else
2747  {
2748  return $errors;
2749  }
2750  }
2751 
2752 
2753 
2757  function delete()
2758  {
2759  global $ilDB;
2760 
2761  $copg_logger = ilLoggerFactory::getLogger('copg');
2762  $copg_logger->debug("ilPageObject: Delete called for ID '".$this->getId()."',".
2763  " parent type: '".$this->getParentType()."', ".
2764  " hist nr: '".$this->old_nr."', ".
2765  " lang: '".$this->getLanguage()."', "
2766  );
2767 
2768  $mobs = array();
2769  $files = array();
2770 
2771  if (!$this->page_not_found)
2772  {
2773  $this->buildDom();
2774  $mobs = $this->collectMediaObjects(false);
2775  }
2776  include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
2777  $mobs2 = ilObjMediaObject::_getMobsOfObject($this->getParentType().":pg", $this->getId(), false);
2778  foreach ($mobs2 as $m)
2779  {
2780  if (!in_array($m, $mobs))
2781  {
2782  $mobs[] = $m;
2783  }
2784  }
2785 
2786  $copg_logger->debug("ilPageObject: ... found ".count($mobs)." media objects.");
2787 
2788  $this->__beforeDelete();
2789 
2790  // delete style usages
2791  $this->deleteStyleUsages(false);
2792 
2793  // delete internal links
2794  $this->deleteInternalLinks();
2795 
2796  // delete all mob usages
2797  ilObjMediaObject::_deleteAllUsages($this->getParentType().":pg", $this->getId());
2798 
2799  // delete news
2800  include_once("./Services/News/classes/class.ilNewsItem.php");
2802  $this->getParentType(), $this->getId(), "pg");
2803 
2804  // delete page_object entry
2805  $ilDB->manipulate("DELETE FROM page_object ".
2806  "WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
2807  " AND parent_type= ".$ilDB->quote($this->getParentType(), "text"));
2808  //$this->ilias->db->query($query);
2809 
2810  // delete media objects
2811  foreach ($mobs as $mob_id)
2812  {
2813  $copg_logger->debug("ilPageObject: ... processing mob ".$mob_id.".");
2814 
2815  if(ilObject::_lookupType($mob_id) != 'mob')
2816  {
2817  $copg_logger->debug("ilPageObject: ... type mismatch. Ignoring mob ".$mob_id.".");
2818  continue;
2819  }
2820 
2821  if (ilObject::_exists($mob_id))
2822  {
2823  $copg_logger->debug("ilPageObject: ... delete mob ".$mob_id.".");
2824 
2825  $mob_obj = new ilObjMediaObject($mob_id);
2826  $mob_obj->delete();
2827  }
2828  else
2829  {
2830  $copg_logger->debug("ilPageObject: ... missing mob ".$mob_id.".");
2831  }
2832  }
2833 
2834 
2835  /* delete public and private notes (see PageObjectGUI->getNotesHTML())
2836  as they can be seen as personal data we are keeping them for now
2837  include_once("Services/Notes/classes/class.ilNote.php");
2838  foreach(array(IL_NOTE_PRIVATE, IL_NOTE_PUBLIC) as $note_type)
2839  {
2840  foreach(ilNote::_getNotesOfObject($this->getParentId(), $this->getId(),
2841  $this->getParentType(), $note_type) as $note)
2842  {
2843  $note->delete();
2844  }
2845  }
2846  */
2847  }
2848 
2854  protected final function __beforeDelete()
2855  {
2856  // pc classes hook
2857  include_once("./Services/COPage/classes/class.ilCOPagePCDef.php");
2859  foreach ($defs as $def)
2860  {
2862  $cl = $def["pc_class"];
2863  call_user_func($def["pc_class"].'::beforePageDelete', $this);
2864  }
2865  }
2866 
2872  protected final function __afterHistoryEntry($a_old_domdoc, $a_old_content, $a_old_nr)
2873  {
2874  // save style usage
2875  $this->saveStyleUsage($a_old_domdoc, $a_old_nr);
2876 
2877  // pc classes hook
2878  include_once("./Services/COPage/classes/class.ilCOPagePCDef.php");
2880  foreach ($defs as $def)
2881  {
2883  $cl = $def["pc_class"];
2884  call_user_func($def["pc_class"].'::afterPageHistoryEntry', $this, $a_old_domdoc, $a_old_content, $a_old_nr);
2885  }
2886  }
2887 
2893  function saveStyleUsage($a_domdoc, $a_old_nr = 0)
2894  {
2895  global $ilDB;
2896 
2897  // media aliases
2898  $xpath = new DOMXPath($a_domdoc);
2899  $path = "//Paragraph | //Section | //MediaAlias | //FileItem".
2900  " | //Table | //TableData | //Tabs | //List";
2901  $nodes = $xpath->query($path);
2902  $usages = array();
2903  foreach($nodes as $node)
2904  {
2905  switch ($node->localName)
2906  {
2907  case "Paragraph":
2908  $sname = $node->getAttribute("Characteristic");
2909  $stype = "text_block";
2910  $template = 0;
2911  break;
2912 
2913  case "Section":
2914  $sname = $node->getAttribute("Characteristic");
2915  $stype = "section";
2916  $template = 0;
2917  break;
2918 
2919  case "MediaAlias":
2920  $sname = $node->getAttribute("Class");
2921  $stype = "media_cont";
2922  $template = 0;
2923  break;
2924 
2925  case "FileItem":
2926  $sname = $node->getAttribute("Class");
2927  $stype = "flist_li";
2928  $template = 0;
2929  break;
2930 
2931  case "Table":
2932  $sname = $node->getAttribute("Template");
2933  if ($sname == "")
2934  {
2935  $sname = $node->getAttribute("Class");
2936  $stype = "table";
2937  $template = 0;
2938  }
2939  else
2940  {
2941  $stype = "table";
2942  $template = 1;
2943  }
2944  break;
2945 
2946  case "TableData":
2947  $sname = $node->getAttribute("Class");
2948  $stype = "table_cell";
2949  $template = 0;
2950  break;
2951 
2952  case "Tabs":
2953  $sname = $node->getAttribute("Template");
2954  if ($sname != "")
2955  {
2956  if ($node->getAttribute("Type") == "HorizontalAccordion")
2957  {
2958  $stype = "haccordion";
2959  }
2960  if ($node->getAttribute("Type") == "VerticalAccordion")
2961  {
2962  $stype = "vaccordion";
2963  }
2964  }
2965  $template = 1;
2966  break;
2967 
2968  case "List":
2969  $sname = $node->getAttribute("Class");
2970  if ($node->getAttribute("Type") == "Ordered")
2971  {
2972  $stype = "list_o";
2973  }
2974  else
2975  {
2976  $stype = "list_u";
2977  }
2978  $template = 0;
2979  break;
2980  }
2981  if ($sname != "" && $stype != "")
2982  {
2983  $usages[$sname.":".$stype.":".$template] = array("sname" => $sname,
2984  "stype" => $stype, "template" => $template);
2985  }
2986  }
2987 
2988 
2989  $this->deleteStyleUsages($a_old_nr);
2990 
2991  foreach ($usages as $u)
2992  {
2993  $id = $ilDB->nextId('page_style_usage');
2994 
2995  $ilDB->manipulate("INSERT INTO page_style_usage ".
2996  "(id, page_id, page_type, page_lang, page_nr, template, stype, sname) VALUES (".
2997  $ilDB->quote($id, "integer").",".
2998  $ilDB->quote($this->getId(), "integer").",".
2999  $ilDB->quote($this->getParentType(), "text").",".
3000  $ilDB->quote($this->getLanguage(), "text").",".
3001  $ilDB->quote($a_old_nr, "integer").",".
3002  $ilDB->quote($u["template"], "integer").",".
3003  $ilDB->quote($u["stype"], "text").",".
3004  $ilDB->quote($u["sname"], "text").
3005  ")");
3006  }
3007  }
3008 
3015  function deleteStyleUsages($a_old_nr = 0)
3016  {
3017  global $ilDB;
3018 
3019  if ($a_old_nr !== false)
3020  {
3021  $and_old_nr = " AND page_nr = ".$ilDB->quote($a_old_nr, "integer");
3022  }
3023 
3024  $ilDB->manipulate("DELETE FROM page_style_usage WHERE ".
3025  " page_id = ".$ilDB->quote($this->getId(), "integer").
3026  " AND page_type = ".$ilDB->quote($this->getParentType(), "text").
3027  " AND page_lang = ".$ilDB->quote($this->getLanguage(), "text").
3028  $and_old_nr
3029  );
3030  }
3031 
3032 
3037  // @todo: move to content include class
3039  {
3040  include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
3041  include_once("./Modules/File/classes/class.ilObjFile.php");
3043  $this->getId());
3045  $this->getId());
3046  $objs = array_merge($mobs, $files);
3047  return ilObject::_getLastUpdateOfObjects($objs);
3048  }
3049 
3057  {
3058  include_once("./Services/Link/classes/class.ilInternalLink.php");
3060  $this->getLanguage());
3061  }
3062 
3063 
3069  // @todo: move to specific classes, internal link use info
3070  function saveInternalLinks($a_domdoc)
3071  {
3072  global $ilDB;
3073 
3074  $this->deleteInternalLinks();
3075 
3076  // query IntLink elements
3077  $xpath = new DOMXPath($a_domdoc);
3078  $nodes = $xpath->query('//IntLink');
3079  foreach($nodes as $node)
3080  {
3081  $link_type = $node->getAttribute("Type");
3082 
3083  switch ($link_type)
3084  {
3085  case "StructureObject":
3086  $t_type = "st";
3087  break;
3088 
3089  case "PageObject":
3090  $t_type = "pg";
3091  break;
3092 
3093  case "GlossaryItem":
3094  $t_type = "git";
3095  break;
3096 
3097  case "MediaObject":
3098  $t_type = "mob";
3099  break;
3100 
3101  case "RepositoryItem":
3102  $t_type = "obj";
3103  break;
3104 
3105  case "File":
3106  $t_type = "file";
3107  break;
3108 
3109  case "WikiPage":
3110  $t_type = "wpage";
3111  break;
3112 
3113  case "User":
3114  $t_type = "user";
3115  break;
3116  }
3117 
3118  $target = $node->getAttribute("Target");
3119  $target_arr = explode("_", $target);
3120  $t_id = $target_arr[count($target_arr) - 1];
3121 
3122  // link to other internal object
3123  if (is_int(strpos($target, "__")))
3124  {
3125  $t_inst = 0;
3126  }
3127  else // link to unresolved object in other installation
3128  {
3129  $t_inst = $target_arr[1];
3130  }
3131 
3132  if ($t_id > 0)
3133  {
3134  ilInternalLink::_saveLink($this->getParentType().":pg", $this->getId(), $t_type,
3135  $t_id, $t_inst, $this->getLanguage());
3136  }
3137  }
3138  }
3139 
3143  function create()
3144  {
3145  $this->createFromXML();
3146  }
3147 
3155  function deleteContent($a_hid, $a_update = true, $a_pcid = "")
3156  {
3157  $curr_node = $this->getContentNode($a_hid, $a_pcid);
3158  $curr_node->unlink_node($curr_node);
3159  if ($a_update)
3160  {
3161  return $this->update();
3162  }
3163  }
3164 
3165 
3173  function deleteContents($a_hids, $a_update = true, $a_self_ass = false)
3174  {
3175  if (!is_array($a_hids))
3176  {
3177  return;
3178  }
3179  foreach($a_hids as $a_hid)
3180  {
3181  $a_hid = explode(":", $a_hid);
3182 //echo "-".$a_hid[0]."-".$a_hid[1]."-";
3183 
3184 // @todo 1: hook
3185  // do not delete question nodes in assessment pages
3186  if (!$this->checkForTag("Question", $a_hid[0], $a_hid[1]) || $a_self_ass)
3187  {
3188  $curr_node = $this->getContentNode($a_hid[0], $a_hid[1]);
3189  if (is_object($curr_node))
3190  {
3191  $parent_node = $curr_node->parent_node();
3192  if ($parent_node->node_name() != "TableRow")
3193  {
3194  $curr_node->unlink_node($curr_node);
3195  }
3196  }
3197  }
3198  }
3199  if ($a_update)
3200  {
3201  return $this->update();
3202  }
3203  }
3204 
3210  function cutContents($a_hids)
3211  {
3212  $this->copyContents($a_hids);
3213  return $this->deleteContents($a_hids, true, $this->getPageConfig()->getEnableSelfAssessment());
3214  }
3215 
3221  function copyContents($a_hids)
3222  {
3223  global $ilUser;
3224 //var_dump($a_hids);
3225  if (!is_array($a_hids))
3226  {
3227  return;
3228  }
3229 
3230  $time = date("Y-m-d H:i:s", time());
3231 
3232  $hier_ids = array();
3233  $skip = array();
3234  foreach($a_hids as $a_hid)
3235  {
3236  if ($a_hid == "")
3237  {
3238  continue;
3239  }
3240  $a_hid = explode(":", $a_hid);
3241 
3242  // check, whether new hid is child of existing one or vice versa
3243  reset($hier_ids);
3244  foreach($hier_ids as $h)
3245  {
3246  if($h."_" == substr($a_hid[0], 0, strlen($h) + 1))
3247  {
3248  $skip[] = $a_hid[0];
3249  }
3250  if($a_hid[0]."_" == substr($h, 0, strlen($a_hid[0]) + 1))
3251  {
3252  $skip[] = $h;
3253  }
3254  }
3255  $pc_id[$a_hid[0]] = $a_hid[1];
3256  if ($a_hid[0] != "")
3257  {
3258  $hier_ids[$a_hid[0]] = $a_hid[0];
3259  }
3260  }
3261  foreach ($skip as $s)
3262  {
3263  unset($hier_ids[$s]);
3264  }
3265  include_once("./Services/COPage/classes/class.ilPageContent.php");
3266  $hier_ids = ilPageContent::sortHierIds($hier_ids);
3267  $nr = 1;
3268  foreach($hier_ids as $hid)
3269  {
3270  $curr_node = $this->getContentNode($hid, $pc_id[$hid]);
3271  if (is_object($curr_node))
3272  {
3273  if ($curr_node->node_name() == "PageContent")
3274  {
3275  $content = $this->dom->dump_node($curr_node);
3276  // remove pc and hier ids
3277  $content = preg_replace('/PCID=\"[a-z0-9]*\"/i',"",$content);
3278  $content = preg_replace('/HierId=\"[a-z0-9_]*\"/i',"",$content);
3279 
3280  $ilUser->addToPCClipboard($content, $time, $nr);
3281  $nr++;
3282  }
3283  }
3284  }
3285  include_once("./Modules/LearningModule/classes/class.ilEditClipboard.php");
3287  }
3288 
3292  function pasteContents($a_hier_id, $a_self_ass = false)
3293  {
3294  global $ilUser;
3295 
3296  $a_hid = explode(":", $a_hier_id);
3297  $content = $ilUser->getPCClipboardContent();
3298 
3299  // we insert from last to first, because we insert all at the
3300  // same hier_id
3301  for ($i = count($content) - 1; $i >= 0; $i--)
3302  {
3303 
3304  $c = $content[$i];
3305  $temp_dom = domxml_open_mem('<?xml version="1.0" encoding="UTF-8"?>'.$c,
3306  DOMXML_LOAD_PARSING, $error);
3307  if(empty($error))
3308  {
3309  $this->handleCopiedContent($temp_dom, $a_self_ass);
3310  $xpc = xpath_new_context($temp_dom);
3311  $path = "//PageContent";
3312  $res = xpath_eval($xpc, $path);
3313  if (count($res->nodeset) > 0)
3314  {
3315  $new_pc_node = $res->nodeset[0];
3316  $cloned_pc_node = $new_pc_node->clone_node (true);
3317  $cloned_pc_node->unlink_node ($cloned_pc_node);
3318  $this->insertContentNode ($cloned_pc_node, $a_hid[0],
3319  IL_INSERT_AFTER, $a_hid[1]);
3320  }
3321  }
3322  else
3323  {
3324 //var_dump($error);
3325  }
3326  }
3327  $e = $this->update();
3328 //var_dump($e);
3329  }
3330 
3334  function switchEnableMultiple($a_hids, $a_update = true, $a_self_ass = false)
3335  {
3336  if (!is_array($a_hids))
3337  {
3338  return;
3339  }
3340  $obj = & $this->content_obj;
3341 
3342  foreach($a_hids as $a_hid)
3343  {
3344  $a_hid = explode(":", $a_hid);
3345  $curr_node = $this->getContentNode($a_hid[0], $a_hid[1]);
3346  if (is_object($curr_node))
3347  {
3348  if ($curr_node->node_name() == "PageContent")
3349  {
3350  $cont_obj = $this->getContentObject($a_hid[0], $a_hid[1]);
3351  if ($cont_obj->isEnabled ())
3352  {
3353  // do not deactivate question nodes in assessment pages
3354  if (!$this->checkForTag("Question", $a_hid[0], $a_hid[1]) || $a_self_ass)
3355  {
3356  $cont_obj->disable();
3357  }
3358  }
3359  else
3360  {
3361  $cont_obj->enable();
3362  }
3363  }
3364  }
3365  }
3366 
3367  if ($a_update)
3368  {
3369  return $this->update();
3370  }
3371  }
3372 
3373 
3381  function deleteContentFromHierId($a_hid, $a_update = true)
3382  {
3383  $hier_ids = $this->getHierIds();
3384 
3385  // iterate all hierarchical ids
3386  foreach ($hier_ids as $hier_id)
3387  {
3388  // delete top level nodes only
3389  if (!is_int(strpos($hier_id, "_")))
3390  {
3391  if ($hier_id != "pg" && $hier_id >= $a_hid)
3392  {
3393  $curr_node = $this->getContentNode($hier_id);
3394  $curr_node->unlink_node($curr_node);
3395  }
3396  }
3397  }
3398  if ($a_update)
3399  {
3400  return $this->update();
3401  }
3402  }
3403 
3411  function deleteContentBeforeHierId($a_hid, $a_update = true)
3412  {
3413  $hier_ids = $this->getHierIds();
3414 
3415  // iterate all hierarchical ids
3416  foreach ($hier_ids as $hier_id)
3417  {
3418  // delete top level nodes only
3419  if (!is_int(strpos($hier_id, "_")))
3420  {
3421  if ($hier_id != "pg" && $hier_id < $a_hid)
3422  {
3423  $curr_node = $this->getContentNode($hier_id);
3424  $curr_node->unlink_node($curr_node);
3425  }
3426  }
3427  }
3428  if ($a_update)
3429  {
3430  return $this->update();
3431  }
3432  }
3433 
3434 
3442  static function _moveContentAfterHierId(&$a_source_page, &$a_target_page, $a_hid)
3443  {
3444  $hier_ids = $a_source_page->getHierIds();
3445 
3446  $copy_ids = array();
3447 
3448  // iterate all hierarchical ids
3449  foreach ($hier_ids as $hier_id)
3450  {
3451  // move top level nodes only
3452  if (!is_int(strpos($hier_id, "_")))
3453  {
3454  if ($hier_id != "pg" && $hier_id >= $a_hid)
3455  {
3456  $copy_ids[] = $hier_id;
3457  }
3458  }
3459  }
3460  asort($copy_ids);
3461 
3462  $parent_node = $a_target_page->getContentNode("pg");
3463  $target_dom = $a_target_page->getDom();
3464  $parent_childs = $parent_node->child_nodes();
3465  $cnt_parent_childs = count($parent_childs);
3466 //echo "-$cnt_parent_childs-";
3467  $first_child = $parent_childs[0];
3468  foreach($copy_ids as $copy_id)
3469  {
3470  $source_node = $a_source_page->getContentNode($copy_id);
3471 
3472  $new_node = $source_node->clone_node(true);
3473  $new_node->unlink_node($new_node);
3474 
3475  $source_node->unlink_node($source_node);
3476 
3477  if($cnt_parent_childs == 0)
3478  {
3479  $new_node = $parent_node->append_child($new_node);
3480  }
3481  else
3482  {
3483  //$target_dom->import_node($new_node);
3484  $new_node = $first_child->insert_before($new_node, $first_child);
3485  }
3486  $parent_childs = $parent_node->child_nodes();
3487 
3488  //$cnt_parent_childs++;
3489  }
3490 
3491  $a_target_page->update();
3492  $a_source_page->update();
3493 
3494  }
3495 
3499  function insertContent(&$a_cont_obj, $a_pos, $a_mode = IL_INSERT_AFTER, $a_pcid = "")
3500  {
3501 //echo "-".$a_pos."-".$a_pcid."-";
3502  // move mode into container elements is always INSERT_CHILD
3503  $curr_node = $this->getContentNode($a_pos, $a_pcid);
3504  $curr_name = $curr_node->node_name();
3505 
3506  // @todo: try to generalize this
3507  if (($curr_name == "TableData") || ($curr_name == "PageObject") ||
3508  ($curr_name == "ListItem") || ($curr_name == "Section")
3509  || ($curr_name == "Tab") || ($curr_name == "ContentPopup"))
3510  {
3511  $a_mode = IL_INSERT_CHILD;
3512  }
3513 
3514  $hid = $curr_node->get_attribute("HierId");
3515  if ($hid != "")
3516  {
3517 //echo "-".$a_pos."-".$hid."-";
3518  $a_pos = $hid;
3519  }
3520 
3521  if($a_mode != IL_INSERT_CHILD) // determine parent hierarchical id
3522  { // of sibling at $a_pos
3523  $pos = explode("_", $a_pos);
3524  $target_pos = array_pop($pos);
3525  $parent_pos = implode($pos, "_");
3526  }
3527  else // if we should insert a child, $a_pos is alreade the hierarchical id
3528  { // of the parent node
3529  $parent_pos = $a_pos;
3530  }
3531 
3532  // get the parent node
3533  if($parent_pos != "")
3534  {
3535  $parent_node = $this->getContentNode($parent_pos);
3536  }
3537  else
3538  {
3539  $parent_node = $this->getNode();
3540  }
3541 
3542  // count the parent children
3543  $parent_childs = $parent_node->child_nodes();
3544  $cnt_parent_childs = count($parent_childs);
3545 //echo "ZZ$a_mode";
3546  switch ($a_mode)
3547  {
3548  // insert new node after sibling at $a_pos
3549  case IL_INSERT_AFTER:
3550  $new_node = $a_cont_obj->getNode();
3551  //$a_pos = ilPageContent::incEdId($a_pos);
3552  //$curr_node = $this->getContentNode($a_pos);
3553 //echo "behind $a_pos:";
3554  if($succ_node = $curr_node->next_sibling())
3555  {
3556  $new_node = $succ_node->insert_before($new_node, $succ_node);
3557  }
3558  else
3559  {
3560 //echo "movin doin append_child";
3561  $new_node = $parent_node->append_child($new_node);
3562  }
3563  $a_cont_obj->setNode($new_node);
3564  break;
3565 
3566  case IL_INSERT_BEFORE:
3567 //echo "INSERT_BEF";
3568  $new_node = $a_cont_obj->getNode();
3569  $succ_node = $this->getContentNode($a_pos);
3570  $new_node = $succ_node->insert_before($new_node, $succ_node);
3571  $a_cont_obj->setNode($new_node);
3572  break;
3573 
3574  // insert new node as first child of parent $a_pos (= $a_parent)
3575  case IL_INSERT_CHILD:
3576 //echo "insert as child:parent_childs:$cnt_parent_childs:<br>";
3577  $new_node = $a_cont_obj->getNode();
3578  if($cnt_parent_childs == 0)
3579  {
3580  $new_node = $parent_node->append_child($new_node);
3581  }
3582  else
3583  {
3584  $new_node = $parent_childs[0]->insert_before($new_node, $parent_childs[0]);
3585  }
3586  $a_cont_obj->setNode($new_node);
3587 //echo "PP";
3588  break;
3589  }
3590 
3591  //check for PlaceHolder to remove in EditMode-keep in Layout Mode
3592  if (!$this->getPageConfig()->getEnablePCType("PlaceHolder")) {
3593  $sub_nodes = $curr_node->child_nodes() ;
3594  foreach ( $sub_nodes as $sub_node ) {
3595  if ($sub_node->node_name() == "PlaceHolder") {
3596  $curr_node->unlink_node();
3597  }
3598  }
3599  }
3600  }
3601 
3605  function insertContentNode(&$a_cont_node, $a_pos, $a_mode = IL_INSERT_AFTER, $a_pcid = "")
3606  {
3607  // move mode into container elements is always INSERT_CHILD
3608  $curr_node = $this->getContentNode($a_pos, $a_pcid);
3609  $curr_name = $curr_node->node_name();
3610 
3611  // @todo: try to generalize
3612  if (($curr_name == "TableData") || ($curr_name == "PageObject") ||
3613  ($curr_name == "ListItem") || ($curr_name == "Section")
3614  || ($curr_name == "Tab") || ($curr_name == "ContentPopup"))
3615  {
3616  $a_mode = IL_INSERT_CHILD;
3617  }
3618 
3619  $hid = $curr_node->get_attribute("HierId");
3620  if ($hid != "")
3621  {
3622  $a_pos = $hid;
3623  }
3624 
3625  if($a_mode != IL_INSERT_CHILD) // determine parent hierarchical id
3626  { // of sibling at $a_pos
3627  $pos = explode("_", $a_pos);
3628  $target_pos = array_pop($pos);
3629  $parent_pos = implode($pos, "_");
3630  }
3631  else // if we should insert a child, $a_pos is alreade the hierarchical id
3632  { // of the parent node
3633  $parent_pos = $a_pos;
3634  }
3635 
3636  // get the parent node
3637  if($parent_pos != "")
3638  {
3639  $parent_node = $this->getContentNode($parent_pos);
3640  }
3641  else
3642  {
3643  $parent_node = $this->getNode();
3644  }
3645 
3646  // count the parent children
3647  $parent_childs = $parent_node->child_nodes();
3648  $cnt_parent_childs = count($parent_childs);
3649 
3650  switch ($a_mode)
3651  {
3652  // insert new node after sibling at $a_pos
3653  case IL_INSERT_AFTER:
3654  //$new_node = $a_cont_obj->getNode();
3655  if($succ_node = $curr_node->next_sibling())
3656  {
3657  $a_cont_node = $succ_node->insert_before($a_cont_node, $succ_node);
3658  }
3659  else
3660  {
3661  $a_cont_node = $parent_node->append_child($a_cont_node);
3662  }
3663  //$a_cont_obj->setNode($new_node);
3664  break;
3665 
3666  case IL_INSERT_BEFORE:
3667  //$new_node = $a_cont_obj->getNode();
3668  $succ_node = $this->getContentNode($a_pos);
3669  $a_cont_node = $succ_node->insert_before($a_cont_node, $succ_node);
3670  //$a_cont_obj->setNode($new_node);
3671  break;
3672 
3673  // insert new node as first child of parent $a_pos (= $a_parent)
3674  case IL_INSERT_CHILD:
3675  //$new_node = $a_cont_obj->getNode();
3676  if($cnt_parent_childs == 0)
3677  {
3678  $a_cont_node = $parent_node->append_child($a_cont_node);
3679  }
3680  else
3681  {
3682  $a_cont_node = $parent_childs[0]->insert_before($a_cont_node, $parent_childs[0]);
3683  }
3684  //$a_cont_obj->setNode($new_node);
3685  break;
3686  }
3687  }
3688 
3693  function moveContentBefore($a_source, $a_target, $a_spcid = "", $a_tpcid = "")
3694  {
3695  if($a_source == $a_target)
3696  {
3697  return;
3698  }
3699 
3700  // clone the node
3701  $content = $this->getContentObject($a_source, $a_spcid);
3702  $source_node = $content->getNode();
3703  $clone_node = $source_node->clone_node(true);
3704 
3705  // delete source node
3706  $this->deleteContent($a_source, false, $a_spcid);
3707 
3708  // insert cloned node at target
3709  $content->setNode($clone_node);
3710  $this->insertContent($content, $a_target, IL_INSERT_BEFORE, $a_tpcid);
3711  return $this->update();
3712 
3713  }
3714 
3719  function moveContentAfter($a_source, $a_target, $a_spcid = "", $a_tpcid = "")
3720  {
3721  if($a_source == $a_target)
3722  {
3723  return;
3724  }
3725 
3726  // clone the node
3727  $content = $this->getContentObject($a_source, $a_spcid);
3728  $source_node = $content->getNode();
3729  $clone_node = $source_node->clone_node(true);
3730 
3731  // delete source node
3732  $this->deleteContent($a_source, false, $a_spcid);
3733 
3734  // insert cloned node at target
3735  $content->setNode($clone_node);
3736  $this->insertContent($content, $a_target, IL_INSERT_AFTER, $a_tpcid);
3737  return $this->update();
3738  }
3739 
3743  // @todo: move to paragraph
3745  {
3746  $a_content = preg_replace('/\[com\]/i',"<Comment>",$a_content);
3747  $a_content = preg_replace('/\[\/com\]/i',"</Comment>",$a_content);
3748  $a_content = preg_replace('/\[emp]/i',"<Emph>",$a_content);
3749  $a_content = preg_replace('/\[\/emp\]/i',"</Emph>",$a_content);
3750  $a_content = preg_replace('/\[str]/i',"<Strong>",$a_content);
3751  $a_content = preg_replace('/\[\/str\]/i',"</Strong>",$a_content);
3752  }
3753 
3758  function insertInstIntoIDs($a_inst, $a_res_ref_to_obj_id = true)
3759  {
3760  // insert inst id into internal links
3761  $xpc = xpath_new_context($this->dom);
3762  $path = "//IntLink";
3763  $res = xpath_eval($xpc, $path);
3764  for($i = 0; $i < count($res->nodeset); $i++)
3765  {
3766  $target = $res->nodeset[$i]->get_attribute("Target");
3767  $type = $res->nodeset[$i]->get_attribute("Type");
3768 
3769  if (substr($target, 0, 4) == "il__")
3770  {
3771  $id = substr($target, 4, strlen($target) - 4);
3772 
3773  // convert repository links obj_<ref_id> to <type>_<obj_id>
3774  // this leads to bug 6685.
3775  if ($a_res_ref_to_obj_id && $type == "RepositoryItem")
3776  {
3777  $id_arr = explode("_", $id);
3778 
3779  // changed due to bug 6685
3780  $ref_id = $id_arr[1];
3781  $obj_id = ilObject::_lookupObjId($id_arr[1]);
3782 
3783  $otype = ilObject::_lookupType($obj_id);
3784  if ($obj_id > 0)
3785  {
3786  // changed due to bug 6685
3787  // the ref_id should be used, if the content is
3788  // imported on the same installation
3789  // the obj_id should be used, if a different
3790  // installation imports, but has an import_id for
3791  // the object id.
3792  $id = $otype."_".$obj_id."_".$ref_id;
3793  //$id = $otype."_".$ref_id;
3794  }
3795  }
3796  $new_target = "il_".$a_inst."_".$id;
3797  $res->nodeset[$i]->set_attribute("Target", $new_target);
3798  }
3799  }
3800  unset($xpc);
3801 
3802  // @todo: move to media/fileitems/questions, ...
3803 
3804  // insert inst id into media aliases
3805  $xpc = xpath_new_context($this->dom);
3806  $path = "//MediaAlias";
3807  $res = xpath_eval($xpc, $path);
3808  for($i = 0; $i < count($res->nodeset); $i++)
3809  {
3810  $origin_id = $res->nodeset[$i]->get_attribute("OriginId");
3811  if (substr($origin_id, 0, 4) == "il__")
3812  {
3813  $new_id = "il_".$a_inst."_".substr($origin_id, 4, strlen($origin_id) - 4);
3814  $res->nodeset[$i]->set_attribute("OriginId", $new_id);
3815  }
3816  }
3817  unset($xpc);
3818 
3819  // insert inst id file item identifier entries
3820  $xpc = xpath_new_context($this->dom);
3821  $path = "//FileItem/Identifier";
3822  $res = xpath_eval($xpc, $path);
3823  for($i = 0; $i < count($res->nodeset); $i++)
3824  {
3825  $origin_id = $res->nodeset[$i]->get_attribute("Entry");
3826  if (substr($origin_id, 0, 4) == "il__")
3827  {
3828  $new_id = "il_".$a_inst."_".substr($origin_id, 4, strlen($origin_id) - 4);
3829  $res->nodeset[$i]->set_attribute("Entry", $new_id);
3830  }
3831  }
3832  unset($xpc);
3833 
3834  // insert inst id into question references
3835  $xpc = xpath_new_context($this->dom);
3836  $path = "//Question";
3837  $res = xpath_eval($xpc, $path);
3838  for($i = 0; $i < count($res->nodeset); $i++)
3839  {
3840  $qref = $res->nodeset[$i]->get_attribute("QRef");
3841 //echo "<br>setted:".$qref;
3842  if (substr($qref, 0, 4) == "il__")
3843  {
3844  $new_id = "il_".$a_inst."_".substr($qref, 4, strlen($qref) - 4);
3845 //echo "<br>setting:".$new_id;
3846  $res->nodeset[$i]->set_attribute("QRef", $new_id);
3847  }
3848  }
3849  unset($xpc);
3850 
3851  // insert inst id into content snippets
3852  $xpc = xpath_new_context($this->dom);
3853  $path = "//ContentInclude";
3854  $res = xpath_eval($xpc, $path);
3855  for($i = 0; $i < count($res->nodeset); $i++)
3856  {
3857  $ci = $res->nodeset[$i]->get_attribute("InstId");
3858  if ($ci == "")
3859  {
3860  $res->nodeset[$i]->set_attribute("InstId", $a_inst);
3861  }
3862  }
3863  unset($xpc);
3864 
3865  }
3866 
3870  function checkPCIds()
3871  {
3872  $this->builddom();
3873  $mydom = $this->dom;
3874 
3875  $sep = $path = "";
3876  foreach ($this->id_elements as $el)
3877  {
3878  $path.= $sep."//".$el."[not(@PCID)]";
3879  $sep = " | ";
3880  $path.= $sep."//".$el."[@PCID='']";
3881  }
3882 
3883  $xpc = xpath_new_context($mydom);
3884  $res = & xpath_eval($xpc, $path);
3885 
3886  if (count ($res->nodeset) > 0)
3887  {
3888  return false;
3889  }
3890  return true;
3891  }
3892 
3899  function getAllPCIds()
3900  {
3901  $this->builddom();
3902  $mydom = $this->dom;
3903 
3904  $pcids = array();
3905 
3906  $sep = $path = "";
3907  foreach ($this->id_elements as $el)
3908  {
3909  $path.= $sep."//".$el."[@PCID]";
3910  $sep = " | ";
3911  }
3912 
3913  // get existing ids
3914  $xpc = xpath_new_context($mydom);
3915  $res = & xpath_eval($xpc, $path);
3916 
3917  for ($i = 0; $i < count ($res->nodeset); $i++)
3918  {
3919  $node = $res->nodeset[$i];
3920  $pcids[] = $node->get_attribute("PCID");
3921  }
3922  return $pcids;
3923  }
3924 
3931  function existsPCId($a_pc_id)
3932  {
3933  $this->builddom();
3934  $mydom = $this->dom;
3935 
3936  $pcids = array();
3937 
3938  $sep = $path = "";
3939  foreach ($this->id_elements as $el)
3940  {
3941  $path.= $sep."//".$el."[@PCID='".$a_pc_id."']";
3942  $sep = " | ";
3943  }
3944 
3945  // get existing ids
3946  $xpc = xpath_new_context($mydom);
3947  $res = & xpath_eval($xpc, $path);
3948  return (count($res->nodeset) > 0);
3949  }
3950 
3957  function generatePcId($a_pc_ids = false)
3958  {
3959  if ($a_pc_ids === false)
3960  {
3961  $a_pc_ids = $this->getAllPCIds();
3962  }
3963  $id = ilUtil::randomHash(10, $a_pc_ids);
3964  return $id;
3965  }
3966 
3967 
3971  function insertPCIds()
3972  {
3973  $this->builddom();
3974  $mydom = $this->dom;
3975 
3976  $pcids = $this->getAllPCIds();
3977 
3978  // add missing ones
3979  $sep = $path = "";
3980  foreach ($this->id_elements as $el)
3981  {
3982  $path.= $sep."//".$el."[not(@PCID)]";
3983  $sep = " | ";
3984  $path.= $sep."//".$el."[@PCID='']";
3985  $sep = " | ";
3986  }
3987  $xpc = xpath_new_context($mydom);
3988  $res = & xpath_eval($xpc, $path);
3989 
3990  for ($i = 0; $i < count ($res->nodeset); $i++)
3991  {
3992  $node = $res->nodeset[$i];
3993  $id = ilUtil::randomHash(10, $pcids);
3994  $pcids[] = $id;
3995 //echo "setting-".$id."-";
3996  $res->nodeset[$i]->set_attribute("PCID", $id);
3997  }
3998  }
3999 
4004  {
4005  $this->builddom();
4006  $this->addHierIds();
4007  $mydom = $this->dom;
4008 
4009  // get existing ids
4010  $path = "//PageContent";
4011  $xpc = xpath_new_context($mydom);
4012  $res = & xpath_eval($xpc, $path);
4013 
4014  $hashes = array();
4015  require_once("./Services/COPage/classes/class.ilPCParagraph.php");
4016  for ($i = 0; $i < count ($res->nodeset); $i++)
4017  {
4018  $hier_id = $res->nodeset[$i]->get_attribute("HierId");
4019  $pc_id = $res->nodeset[$i]->get_attribute("PCID");
4020  $dump = $mydom->dump_node($res->nodeset[$i]);
4021  if (($hpos = strpos($dump, ' HierId="'.$hier_id.'"')) > 0)
4022  {
4023  $dump = substr($dump, 0, $hpos).
4024  substr($dump, $hpos + strlen(' HierId="'.$hier_id.'"'));
4025  }
4026 
4027  $childs = $res->nodeset[$i]->child_nodes();
4028  $content = "";
4029  if ($childs[0] && $childs[0]->node_name() == "Paragraph")
4030  {
4031  $content = $mydom->dump_node($childs[0]);
4032  $content = substr($content, strpos($content, ">") + 1,
4033  strrpos($content, "<") - (strpos($content, ">") + 1));
4034 //var_dump($content);
4035  $content = ilPCParagraph::xml2output($content);
4036 //var_dump($content);
4037  }
4038  //$hashes[$hier_id] =
4039  // array("PCID" => $pc_id, "hash" => md5($dump));
4040  $hashes[$pc_id] =
4041  array("hier_id" => $hier_id, "hash" => md5($dump), "content" => $content);
4042  }
4043 
4044  return $hashes;
4045  }
4046 
4050 // @todo: move to questions
4051  function getQuestionIds()
4052  {
4053  $this->builddom();
4054  $mydom = $this->dom;
4055 
4056  // Get question IDs
4057  $path = "//Question";
4058  $xpc = xpath_new_context($mydom);
4059  $res = & xpath_eval($xpc, $path);
4060 
4061  $q_ids = array();
4062  include_once("./Services/Link/classes/class.ilInternalLink.php");
4063  for ($i = 0; $i < count ($res->nodeset); $i++)
4064  {
4065  $qref = $res->nodeset[$i]->get_attribute("QRef");
4066 
4067  $inst_id = ilInternalLink::_extractInstOfTarget($qref);
4068  $obj_id = ilInternalLink::_extractObjIdOfTarget($qref);
4069 
4070  if (!($inst_id > 0))
4071  {
4072  if ($obj_id > 0)
4073  {
4074  $q_ids[] = $obj_id;
4075  }
4076  }
4077  }
4078  return $q_ids;
4079  }
4080 
4081 // @todo: move to paragraph
4082  function send_paragraph ($par_id, $filename)
4083  {
4084  $this->builddom();
4085 
4086  $mydom = $this->dom;
4087 
4088  $xpc = xpath_new_context($mydom);
4089 
4090  //$path = "//PageContent[position () = $par_id]/Paragraph";
4091  //$path = "//Paragraph[$par_id]";
4092  $path = "/descendant::Paragraph[position() = $par_id]";
4093 
4094  $res = & xpath_eval($xpc, $path);
4095 
4096  if (count ($res->nodeset) != 1)
4097  die ("Should not happen");
4098 
4099  $context_node = $res->nodeset[0];
4100 
4101  // get plain text
4102 
4103  $childs = $context_node->child_nodes();
4104 
4105  for($j=0; $j<count($childs); $j++)
4106  {
4107  $content .= $mydom->dump_node($childs[$j]);
4108  }
4109 
4110  $content = str_replace("<br />", "\n", $content);
4111  $content = str_replace("<br/>", "\n", $content);
4112 
4113  $plain_content = html_entity_decode($content);
4114 
4115  ilUtil::deliverData($plain_content, $filename);
4116  /*
4117  $file_type = "application/octet-stream";
4118  header("Content-type: ".$file_type);
4119  header("Content-disposition: attachment; filename=\"$filename\"");
4120  echo $plain_content;*/
4121  exit();
4122  }
4123 
4127 // @todo: deprecated?
4128  function getFO()
4129  {
4130  $xml = $this->getXMLFromDom(false, true, true);
4131  $xsl = file_get_contents("./Services/COPage/xsl/page_fo.xsl");
4132  $args = array( '/_xml' => $xml, '/_xsl' => $xsl );
4133  $xh = xslt_create();
4134 
4135  $params = array ();
4136 
4137 
4138  $fo = xslt_process($xh,"arg:/_xml","arg:/_xsl",NULL,$args, $params);
4139  var_dump($fo);
4140  // do some replacements
4141  $fo = str_replace("\n", "", $fo);
4142  $fo = str_replace("<br/>", "<br>", $fo);
4143  $fo = str_replace("<br>", "\n", $fo);
4144 
4145  xslt_free($xh);
4146 
4147  //
4148  $fo = substr($fo, strpos($fo,">") + 1);
4149 //echo "<br><b>fo:</b><br>".htmlentities($fo); flush();
4150  return $fo;
4151  }
4152 
4153  function registerOfflineHandler ($handler) {
4154  $this->offline_handler = $handler;
4155  }
4156 
4164  {
4165  return $this->offline_handler;
4166  }
4167 
4168 
4172  static function _lookupContainsDeactivatedElements($a_id, $a_parent_type, $a_lang = "-")
4173  {
4174  global $ilDB;
4175 
4176  if ($a_lang == "")
4177  {
4178  $a_lang = "-";
4179  }
4180 
4181  $query = "SELECT * FROM page_object WHERE page_id = ".
4182  $ilDB->quote($a_id, "integer")." AND ".
4183  " parent_type = ".$ilDB->quote($a_parent_type, "text")." AND ".
4184  " lang = ".$ilDB->quote($a_lang, "text")." AND ".
4185  " inactive_elements = ".$ilDB->quote(1, "integer");
4186  $obj_set = $ilDB->query($query);
4187 
4188  if ($obj_rec = $obj_set->fetchRow(ilDBConstants::FETCHMODE_ASSOC))
4189  {
4190  return true;
4191  }
4192 
4193  return false;
4194  }
4195 
4203  {
4204  if (strpos($a_content, " Enabled=\"False\""))
4205  {
4206  return true;
4207  }
4208  return false;
4209  }
4210 
4215  {
4216  global $ilDB;
4217 
4218  $h_query = "SELECT * FROM page_history ".
4219  " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
4220  " AND parent_type = ".$ilDB->quote($this->getParentType(), "text").
4221  " AND lang = ".$ilDB->quote($this->getLanguage(), "text").
4222  " ORDER BY hdate DESC";
4223 
4224  $hset = $ilDB->query($h_query);
4225  $hentries = array();
4226 
4227  while ($hrec = $ilDB->fetchAssoc($hset))
4228  {
4229  $hrec["sortkey"] = (int) $hrec["nr"];
4230  $hrec["user"] = (int) $hrec["user_id"];
4231  $hentries[] = $hrec;
4232  }
4233 //var_dump($hentries);
4234  return $hentries;
4235  }
4236 
4240  function getHistoryEntry($a_old_nr)
4241  {
4242  global $ilDB;
4243 
4244  $res = $ilDB->queryF("SELECT * FROM page_history ".
4245  " WHERE page_id = %s ".
4246  " AND parent_type = %s ".
4247  " AND nr = %s".
4248  " AND lang = %s",
4249  array("integer", "text", "integer", "text"),
4250  array($this->getId(), $this->getParentType(), $a_old_nr, $this->getLanguage()));
4251  if ($hrec = $ilDB->fetchAssoc($res))
4252  {
4253  return $hrec;
4254  }
4255 
4256  return false;
4257  }
4258 
4259 
4266  function getHistoryInfo($a_nr)
4267  {
4268  global $ilDB;
4269 
4270  // determine previous entry
4271  $and_nr = ($a_nr > 0)
4272  ? " AND nr < ".$ilDB->quote((int) $a_nr, "integer")
4273  : "";
4274  $res = $ilDB->query("SELECT MAX(nr) mnr FROM page_history ".
4275  " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
4276  " AND parent_type = ".$ilDB->quote($this->getParentType(), "text").
4277  " AND lang = ".$ilDB->quote($this->getLanguage(), "text").
4278  $and_nr);
4279  $row = $ilDB->fetchAssoc($res);
4280  if ($row["mnr"] > 0)
4281  {
4282  $res = $ilDB->query("SELECT * FROM page_history ".
4283  " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
4284  " AND parent_type = ".$ilDB->quote($this->getParentType(), "text").
4285  " AND lang = ".$ilDB->quote($this->getLanguage(), "text").
4286  " AND nr = ".$ilDB->quote((int) $row["mnr"], "integer"));
4287  $row = $ilDB->fetchAssoc($res);
4288  $ret["previous"] = $row;
4289  }
4290 
4291  // determine next entry
4292  $res = $ilDB->query("SELECT MIN(nr) mnr FROM page_history ".
4293  " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
4294  " AND parent_type = ".$ilDB->quote($this->getParentType(), "text").
4295  " AND lang = ".$ilDB->quote($this->getLanguage(), "text").
4296  " AND nr > ".$ilDB->quote((int) $a_nr, "integer"));
4297  $row = $ilDB->fetchAssoc($res);
4298  if ($row["mnr"] > 0)
4299  {
4300  $res = $ilDB->query("SELECT * FROM page_history ".
4301  " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
4302  " AND parent_type = ".$ilDB->quote($this->getParentType(), "text").
4303  " AND lang = ".$ilDB->quote($this->getLanguage(), "text").
4304  " AND nr = ".$ilDB->quote((int) $row["mnr"], "integer"));
4305  $row = $ilDB->fetchAssoc($res);
4306  $ret["next"] = $row;
4307  }
4308 
4309  // current
4310  if ($a_nr > 0)
4311  {
4312  $res = $ilDB->query("SELECT * FROM page_history ".
4313  " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
4314  " AND parent_type = ".$ilDB->quote($this->getParentType(), "text").
4315  " AND lang = ".$ilDB->quote($this->getLanguage(), "text").
4316  " AND nr = ".$ilDB->quote((int) $a_nr, "integer"));
4317  $row = $ilDB->fetchAssoc($res);
4318  }
4319  else
4320  {
4321  $res = $ilDB->query("SELECT page_id, last_change hdate, parent_type, parent_id, last_change_user user_id, content, lang FROM page_object ".
4322  " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
4323  " AND parent_type = ".$ilDB->quote($this->getParentType(), "text").
4324  " AND lang = ".$ilDB->quote($this->getLanguage(), "text"));
4325  $row = $ilDB->fetchAssoc($res);
4326  }
4327  $ret["current"] = $row;
4328 
4329  return $ret;
4330  }
4331 
4332  function addChangeDivClasses($a_hashes)
4333  {
4334  $xpc = xpath_new_context($this->dom);
4335  $path = "/*[1]";
4336  $res = xpath_eval($xpc, $path);
4337  $rnode = $res->nodeset[0];
4338 
4339 //echo "A";
4340  foreach($a_hashes as $pc_id => $h)
4341  {
4342 //echo "B";
4343  if ($h["change"] != "")
4344  {
4345  $dc_node = $this->dom->create_element("DivClass");
4346  $dc_node->set_attribute("HierId", $h["hier_id"]);
4347  $dc_node->set_attribute("Class", "ilEdit".$h["change"]);
4348  $dc_node = $rnode->append_child($dc_node);
4349  }
4350  }
4351 //echo "<br><br><br><br><br><br>".htmlentities($this->getXMLFromDom());
4352  }
4353 
4360  function compareVersion($a_left, $a_right)
4361  {
4362  // get page objects
4363  include_once("./Services/COPage/classes/class.ilPageObjectFactory.php");
4364  $l_page = ilPageObjectFactory::getInstance($this->getParentType(), $this->getId(), $a_left);
4365  $r_page = ilPageObjectFactory::getInstance($this->getParentType(), $this->getId(), $a_right);
4366 
4367  $l_hashes = $l_page->getPageContentsHashes();
4368  $r_hashes = $r_page->getPageContentsHashes();
4369  // determine all deleted and changed page elements
4370  foreach ($l_hashes as $pc_id => $h)
4371  {
4372  if (!isset($r_hashes[$pc_id]))
4373  {
4374  $l_hashes[$pc_id]["change"] = "Deleted";
4375  }
4376  else
4377  {
4378  if ($l_hashes[$pc_id]["hash"] != $r_hashes[$pc_id]["hash"])
4379  {
4380  $l_hashes[$pc_id]["change"] = "Modified";
4381  $r_hashes[$pc_id]["change"] = "Modified";
4382 
4383  include_once("./Services/COPage/mediawikidiff/class.WordLevelDiff.php");
4384  // if modified element is a paragraph, highlight changes
4385  if ($l_hashes[$pc_id]["content"] != "" &&
4386  $r_hashes[$pc_id]["content"] != "")
4387  {
4388  $new_left = str_replace("\n", "<br />", $l_hashes[$pc_id]["content"]);
4389  $new_right = str_replace("\n", "<br />", $r_hashes[$pc_id]["content"]);
4390  $wldiff = new WordLevelDiff(array($new_left),
4391  array($new_right));
4392  $new_left = $wldiff->orig();
4393  $new_right = $wldiff->closing();
4394  $l_page->setParagraphContent($l_hashes[$pc_id]["hier_id"], $new_left[0]);
4395  $r_page->setParagraphContent($l_hashes[$pc_id]["hier_id"], $new_right[0]);
4396  }
4397  }
4398  }
4399  }
4400 
4401  // determine all new paragraphs
4402  foreach ($r_hashes as $pc_id => $h)
4403  {
4404  if (!isset($l_hashes[$pc_id]))
4405  {
4406  $r_hashes[$pc_id]["change"] = "New";
4407  }
4408  }
4409  $l_page->addChangeDivClasses($l_hashes);
4410  $r_page->addChangeDivClasses($r_hashes);
4411 
4412  return array("l_page" => $l_page, "r_page" => $r_page,
4413  "l_changes" => $l_hashes, "r_changes" => $r_hashes);
4414  }
4415 
4419  function increaseViewCnt()
4420  {
4421  global $ilDB;
4422 
4423  $ilDB->manipulate("UPDATE page_object ".
4424  " SET view_cnt = view_cnt + 1 ".
4425  " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
4426  " AND parent_type = ".$ilDB->quote($this->getParentType(), "text").
4427  " AND lang = ".$ilDB->quote($this->getLanguage(), "text"));
4428  }
4429 
4437  static function getRecentChanges($a_parent_type, $a_parent_id, $a_period = 30, $a_lang = "")
4438  {
4439  global $ilDB;
4440 
4441  $and_lang = "";
4442  if ($a_lang != "")
4443  {
4444  $and_lang = " AND lang = ".$ilDB->quote($a_lang, "text");
4445  }
4446 
4447  $page_changes = array();
4448  $limit_ts = date('Y-m-d H:i:s', time() - ($a_period * 24 * 60 * 60));
4449  $q = "SELECT * FROM page_object ".
4450  " WHERE parent_id = ".$ilDB->quote($a_parent_id, "integer").
4451  " AND parent_type = ".$ilDB->quote($a_parent_type, "text").
4452  " AND last_change >= ".$ilDB->quote($limit_ts, "timestamp").$and_lang;
4453  // " AND (TO_DAYS(now()) - TO_DAYS(last_change)) <= ".((int)$a_period);
4454  $set = $ilDB->query($q);
4455  while($page = $ilDB->fetchAssoc($set))
4456  {
4457  $page_changes[] = array(
4458  "date" => $page["last_change"],
4459  "id" => $page["page_id"],
4460  "lang" => $page["lang"],
4461  "type" => "page",
4462  "user" => $page["last_change_user"]);
4463  }
4464 
4465  $and_str = "";
4466  if ($a_period > 0)
4467  {
4468  $limit_ts = date('Y-m-d H:i:s', time() - ($a_period * 24 * 60 * 60));
4469  $and_str = " AND hdate >= ".$ilDB->quote($limit_ts, "timestamp")." ";
4470  }
4471 
4472  $q = "SELECT * FROM page_history ".
4473  " WHERE parent_id = ".$ilDB->quote($a_parent_id, "integer").
4474  " AND parent_type = ".$ilDB->quote($a_parent_type, "text").
4475  $and_str.$and_lang;
4476  $set = $ilDB->query($q);
4477  while ($page = $ilDB->fetchAssoc($set))
4478  {
4479  $page_changes[] = array(
4480  "date" => $page["hdate"],
4481  "id" => $page["page_id"],
4482  "lang" => $page["lang"],
4483  "type" => "hist",
4484  "nr" => $page["nr"],
4485  "user" => $page["user_id"]);
4486  }
4487 
4488  $page_changes = ilUtil::sortArray($page_changes, "date", "desc");
4489 
4490  return $page_changes;
4491  }
4492 
4500  static function getAllPages($a_parent_type, $a_parent_id, $a_lang = "-")
4501  {
4502  global $ilDB;
4503 
4504  $and_lang = "";
4505  if ($a_lang != "")
4506  {
4507  $and_lang = " AND lang = ".$ilDB->quote($a_lang, "text");
4508  }
4509 
4510  $page_changes = array();
4511 
4512  $q = "SELECT * FROM page_object ".
4513  " WHERE parent_id = ".$ilDB->quote($a_parent_id, "integer").
4514  " AND parent_type = ".$ilDB->quote($a_parent_type, "text").$and_lang;
4515  $set = $ilDB->query($q);
4516  $pages = array();
4517  while ($page = $ilDB->fetchAssoc($set))
4518  {
4519  $key_add = ($a_lang == "")
4520  ? ":".$page["lang"]
4521  : "";
4522  $pages[$page["page_id"].$key_add] = array(
4523  "date" => $page["last_change"],
4524  "id" => $page["page_id"],
4525  "lang" => $page["lang"],
4526  "user" => $page["last_change_user"]);
4527  }
4528 
4529  return $pages;
4530  }
4531 
4538  static function getNewPages($a_parent_type, $a_parent_id, $a_lang = "-")
4539  {
4540  global $ilDB;
4541 
4542  $and_lang = "";
4543  if ($a_lang != "")
4544  {
4545  $and_lang = " AND lang = ".$ilDB->quote($a_lang, "text");
4546  }
4547 
4548  $pages = array();
4549 
4550  $q = "SELECT * FROM page_object ".
4551  " WHERE parent_id = ".$ilDB->quote($a_parent_id, "integer").
4552  " AND parent_type = ".$ilDB->quote($a_parent_type, "text").$and_lang.
4553  " ORDER BY created DESC";
4554  $set = $ilDB->query($q);
4555  while($page = $ilDB->fetchAssoc($set))
4556  {
4557  if ($page["created"] != "")
4558  {
4559  $pages[] = array(
4560  "created" => $page["created"],
4561  "id" => $page["page_id"],
4562  "lang" => $page["lang"],
4563  "user" => $page["create_user"],
4564  );
4565  }
4566  }
4567 
4568  return $pages;
4569  }
4570 
4577  static function getParentObjectContributors($a_parent_type, $a_parent_id, $a_lang = "-")
4578  {
4579  global $ilDB;
4580 
4581  $and_lang = "";
4582  if ($a_lang != "")
4583  {
4584  $and_lang = " AND lang = ".$ilDB->quote($a_lang, "text");
4585  }
4586 
4587  $contributors = array();
4588  $set = $ilDB->queryF("SELECT last_change_user, lang, page_id FROM page_object ".
4589  " WHERE parent_id = %s AND parent_type = %s ".
4590  " AND last_change_user != %s".$and_lang,
4591  array("integer", "text", "integer"),
4592  array($a_parent_id, $a_parent_type, 0));
4593 
4594  while ($page = $ilDB->fetchAssoc($set))
4595  {
4596  if ($a_lang == "")
4597  {
4598  $contributors[$page["last_change_user"]][$page["page_id"]][$page["lang"]] = 1;
4599  }
4600  else
4601  {
4602  $contributors[$page["last_change_user"]][$page["page_id"]] = 1;
4603  }
4604  }
4605 
4606  $set = $ilDB->queryF("SELECT count(*) as cnt, lang, page_id, user_id FROM page_history ".
4607  " WHERE parent_id = %s AND parent_type = %s AND user_id != %s ".$and_lang.
4608  " GROUP BY page_id, user_id, lang ",
4609  array("integer", "text", "integer"),
4610  array($a_parent_id, $a_parent_type, 0));
4611  while ($hpage = $ilDB->fetchAssoc($set))
4612  {
4613  if ($a_lang == "")
4614  {
4615  $contributors[$hpage["user_id"]][$hpage["page_id"]][$hpage["lang"]] =
4616  $contributors[$hpage["user_id"]][$hpage["page_id"]][$hpage["lang"]] + $hpage["cnt"];
4617  }
4618  else
4619  {
4620  $contributors[$hpage["user_id"]][$hpage["page_id"]] =
4621  $contributors[$hpage["user_id"]][$hpage["page_id"]] + $hpage["cnt"];
4622  }
4623  }
4624 
4625  $c = array();
4626  foreach ($contributors as $k => $co)
4627  {
4628  if (ilObject::_lookupType($k) == "usr")
4629  {
4630  $name = ilObjUser::_lookupName($k);
4631  $c[] = array("user_id" => $k, "pages" => $co,
4632  "lastname" => $name["lastname"], "firstname" => $name["firstname"]);
4633  }
4634  }
4635 
4636  return $c;
4637  }
4638 
4645  static function getPageContributors($a_parent_type, $a_page_id, $a_lang = "-")
4646  {
4647  global $ilDB;
4648 
4649  $and_lang = "";
4650  if ($a_lang != "")
4651  {
4652  $and_lang = " AND lang = ".$ilDB->quote($a_lang, "text");
4653  }
4654 
4655  $contributors = array();
4656  $set = $ilDB->queryF("SELECT last_change_user, lang FROM page_object ".
4657  " WHERE page_id = %s AND parent_type = %s ".
4658  " AND last_change_user != %s".$and_lang,
4659  array("integer", "text", "integer"),
4660  array($a_page_id, $a_parent_type, 0));
4661 
4662  while ($page = $ilDB->fetchAssoc($set))
4663  {
4664  if ($a_lang == "")
4665  {
4666  $contributors[$page["last_change_user"]][$page["lang"]] = 1;
4667  }
4668  else
4669  {
4670  $contributors[$page["last_change_user"]] = 1;
4671  }
4672  }
4673 
4674  $set = $ilDB->queryF("SELECT count(*) as cnt, lang, page_id, user_id FROM page_history ".
4675  " WHERE page_id = %s AND parent_type = %s AND user_id != %s ".$and_lang.
4676  " GROUP BY user_id, page_id, lang ",
4677  array("integer", "text", "integer"),
4678  array($a_page_id, $a_parent_type, 0));
4679  while ($hpage = $ilDB->fetchAssoc($set))
4680  {
4681  if ($a_lang == "")
4682  {
4683  $contributors[$hpage["user_id"]][$page["lang"]] =
4684  $contributors[$hpage["user_id"]][$page["lang"]] + $hpage["cnt"];
4685  }
4686  else
4687  {
4688  $contributors[$hpage["user_id"]] =
4689  $contributors[$hpage["user_id"]] + $hpage["cnt"];
4690  }
4691  }
4692 
4693  $c = array();
4694  foreach ($contributors as $k => $co)
4695  {
4696  include_once "Services/User/classes/class.ilObjUser.php";
4697  $name = ilObjUser::_lookupName($k);
4698  $c[] = array("user_id" => $k, "pages" => $co,
4699  "lastname" => $name["lastname"], "firstname" => $name["firstname"]);
4700  }
4701 
4702  return $c;
4703  }
4704 
4709  {
4710  global $ilDB;
4711 
4712  $ilDB->update("page_object", array(
4713  "rendered_content" => array("clob", $a_content),
4714  "render_md5" => array("text", $a_md5),
4715  "rendered_time" => array("timestamp", ilUtil::now())
4716  ), array(
4717  "page_id" => array("integer", $this->getId()),
4718  "lang" => array("text", $this->getLanguage()),
4719  "parent_type" => array("text", $this->getParentType())
4720  ));
4721  }
4722 
4730  static function getPagesWithLinks($a_parent_type, $a_parent_id, $a_lang = "-")
4731  {
4732  global $ilDB;
4733 
4734  $page_changes = array();
4735 
4736  $and_lang = "";
4737  if ($a_lang != "")
4738  {
4739  $and_lang = " AND lang = ".$ilDB->quote($a_lang, "text");
4740  }
4741 
4742  $q = "SELECT * FROM page_object ".
4743  " WHERE parent_id = ".$ilDB->quote($a_parent_id, "integer").
4744  " AND parent_type = ".$ilDB->quote($a_parent_type, "text").
4745  " AND int_links = ".$ilDB->quote(1, "integer").$and_lang;
4746  $set = $ilDB->query($q);
4747  $pages = array();
4748  while ($page = $ilDB->fetchAssoc($set))
4749  {
4750  $key_add = ($a_lang == "")
4751  ? ":".$page["lang"]
4752  : "";
4753  $pages[$page["page_id"].$key_add] = array(
4754  "date" => $page["last_change"],
4755  "id" => $page["page_id"],
4756  "lang" => $page["lang"],
4757  "user" => $page["last_change_user"]);
4758  }
4759 
4760  return $pages;
4761  }
4762 
4770  {
4771  if (strpos($a_content, "IntLink"))
4772  {
4773  return true;
4774  }
4775  return false;
4776  }
4777 
4782  {
4783  }
4784 
4790 // @todo begin: generalize
4791  function saveInitialOpenedContent($a_type, $a_id, $a_target)
4792  {
4793  $this->buildDom();
4794 
4795  switch($a_type)
4796  {
4797  case "media":
4798  $link_type = "MediaObject";
4799  $a_id = "il__mob_".$a_id;
4800  break;
4801 
4802  case "page":
4803  $link_type = "PageObject";
4804  $a_id = "il__pg_".$a_id;
4805  break;
4806 
4807  case "term":
4808  $link_type = "GlossaryItem";
4809  $a_id = "il__git_".$a_id;
4810  $a_target = "Glossary";
4811  break;
4812  }
4813 
4814  // if type or id missing -> delete InitOpenedContent, if existing
4815  if ($link_type == "" || $a_id == "")
4816  {
4817  $xpc = xpath_new_context($this->dom);
4818  $path = "//PageObject/InitOpenedContent";
4819  $res = xpath_eval($xpc, $path);
4820  if (count($res->nodeset) > 0)
4821  {
4822  $res->nodeset[0]->unlink_node($res->nodeset[0]);
4823  }
4824  }
4825  else
4826  {
4827  $xpc = xpath_new_context($this->dom);
4828  $path = "//PageObject/InitOpenedContent";
4829  $res = xpath_eval($xpc, $path);
4830  if (count($res->nodeset) > 0)
4831  {
4832  $init_node = $res->nodeset[0];
4833  $childs = $init_node->child_nodes();
4834  for($i = 0; $i < count($childs); $i++)
4835  {
4836  if ($childs[$i]->node_name() == "IntLink")
4837  {
4838  $il_node = $childs[$i];
4839  }
4840  }
4841  }
4842  else
4843  {
4844  $path = "//PageObject";
4845  $res = xpath_eval($xpc, $path);
4846  $page_node = $res->nodeset[0];
4847  $init_node = $this->dom->create_element("InitOpenedContent");
4848  $init_node = $page_node->append_child($init_node);
4849  $il_node = $this->dom->create_element("IntLink");
4850  $il_node = $init_node->append_child($il_node);
4851  }
4852  $il_node->set_attribute("Target", $a_id);
4853  $il_node->set_attribute("Type", $link_type);
4854  $il_node->set_attribute("TargetFrame", $a_target);
4855  }
4856 
4857  $ret = $this->update();
4858  }
4859 
4860 
4867  {
4868  $this->buildDom();
4869 
4870  $xpc = xpath_new_context($this->dom);
4871  $path = "//PageObject/InitOpenedContent";
4872  $res = xpath_eval($xpc, $path);
4873  $il_node = null;
4874  if (count($res->nodeset) > 0)
4875  {
4876  $init_node = $res->nodeset[0];
4877  $childs = $init_node->child_nodes();
4878  for($i = 0; $i < count($childs); $i++)
4879  {
4880  if ($childs[$i]->node_name() == "IntLink")
4881  {
4882  $il_node = $childs[$i];
4883  }
4884  }
4885  }
4886  if (!is_null($il_node))
4887  {
4888  $id = $il_node->get_attribute("Target");
4889  $link_type = $il_node->get_attribute("Type");
4890  $target = $il_node->get_attribute("TargetFrame");
4891 
4892  switch($link_type)
4893  {
4894  case "MediaObject":
4895  $type = "media";
4896  break;
4897 
4898  case "PageObject":
4899  $type = "page";
4900  break;
4901 
4902  case "GlossaryItem":
4903  $type = "term";
4904  break;
4905  }
4906  include_once("./Services/Link/classes/class.ilInternalLink.php");
4908  return array("id" => $id, "type" => $type, "target" => $target);
4909  }
4910 
4911  return array();
4912  }
4913 // @todo end
4914 
4925  function beforePageContentUpdate($a_page_content)
4926  {
4927 
4928  }
4929 
4937  function copy($a_id, $a_parent_type = "", $a_parent_id = 0, $a_clone_mobs = false)
4938  {
4939  if ($a_parent_type == "")
4940  {
4941  $a_parent_type = $this->getParentType();
4942  if ($a_parent_id == 0)
4943  {
4944  $a_parent_id = $this->getParentId();
4945  }
4946  }
4947 
4948  include_once("./Services/COPage/classes/class.ilPageObjectFactory.php");
4949  foreach (self::lookupTranslations($this->getParentType(), $this->getId()) as $l)
4950  {
4951  $existed = false;
4952  $orig_page = ilPageObjectFactory::getInstance($this->getParentType(), $this->getId(), 0, $l);
4953  if (ilPageObject::_exists($a_parent_type, $a_id, $l))
4954  {
4955  $new_page_object = ilPageObjectFactory::getInstance($a_parent_type, $a_id, 0, $l);
4956  $existed = true;
4957  }
4958  else
4959  {
4960  $new_page_object = ilPageObjectFactory::getInstance($a_parent_type, 0, 0, $l);
4961  $new_page_object->setParentId($a_parent_id);
4962  $new_page_object->setId($a_id);
4963  }
4964  $new_page_object->setXMLContent($orig_page->copyXMLContent($a_clone_mobs));
4965  $new_page_object->setActive($orig_page->getActive());
4966  $new_page_object->setActivationStart($orig_page->getActivationStart());
4967  $new_page_object->setActivationEnd($orig_page->getActivationEnd());
4968  if ($existed)
4969  {
4970  $new_page_object->buildDom();
4971  $new_page_object->update();
4972  }
4973  else
4974  {
4975  $new_page_object->create();
4976  }
4977  }
4978 
4979  }
4980 
4988  static function lookupTranslations($a_parent_type, $a_id)
4989  {
4990  global $ilDB;
4991 
4992  $set = $ilDB->query("SELECT lang FROM page_object ".
4993  " WHERE page_id = ".$ilDB->quote($a_id, "integer").
4994  " AND parent_type = ".$ilDB->quote($a_parent_type, "text")
4995  );
4996  $langs = array();
4997  while ($rec = $ilDB->fetchAssoc($set))
4998  {
4999  $langs[] = $rec["lang"];
5000  }
5001  return $langs;
5002  }
5003 
5004 
5010  function copyPageToTranslation($a_target_lang)
5011  {
5012  $transl_page = ilPageObjectFactory::getInstance($this->getParentType(),
5013  0, 0, $a_target_lang);
5014  $transl_page->setId($this->getId());
5015  $transl_page->setParentId($this->getParentId());
5016  $transl_page->setXMLContent($this->copyXMLContent());
5017  $transl_page->setActive($this->getActive());
5018  $transl_page->setActivationStart($this->getActivationStart());
5019  $transl_page->setActivationEnd($this->getActivationEnd());
5020  $transl_page->create();
5021  }
5022 
5026 
5030  function getEditLock()
5031  {
5032  global $ilUser, $ilDB;
5033  //return false;
5034  $aset = new ilSetting("adve");
5035 
5036  $min = (int) $aset->get("block_mode_minutes") ;
5037  if ($min > 0)
5038  {
5039  // try to set the lock for the user
5040  $ts = time();
5041  $ilDB->manipulate("UPDATE page_object SET ".
5042  " edit_lock_user = ".$ilDB->quote($ilUser->getId(), "integer").",".
5043  " edit_lock_ts = ".$ilDB->quote($ts, "integer").
5044  " WHERE (edit_lock_user = ".$ilDB->quote($ilUser->getId(), "integer")." OR ".
5045  " edit_lock_ts < ".$ilDB->quote(time() - ($min * 60), "integer").") ".
5046  " AND page_id = ".$ilDB->quote($this->getId(), "integer").
5047  " AND parent_type = ".$ilDB->quote($this->getParentType(), "text")
5048  );
5049 
5050  $set = $ilDB->query("SELECT edit_lock_user FROM page_object ".
5051  " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
5052  " AND parent_type = ".$ilDB->quote($this->getParentType(), "text")
5053  );
5054  $rec = $ilDB->fetchAssoc($set);
5055  if ($rec["edit_lock_user"] != $ilUser->getId())
5056  {
5057  return false;
5058  }
5059  }
5060 
5061  return true;
5062  }
5063 
5067  function releasePageLock()
5068  {
5069  global $ilUser, $ilDB;
5070 
5071  $aset = new ilSetting("adve");
5072 
5073  $min = (int) $aset->get("block_mode_minutes") ;
5074  if ($min > 0)
5075  {
5076  // try to set the lock for the user
5077  $ts = time();
5078  $ilDB->manipulate("UPDATE page_object SET ".
5079  " edit_lock_user = ".$ilDB->quote($ilUser->getId(), "integer").",".
5080  " edit_lock_ts = 0".
5081  " WHERE edit_lock_user = ".$ilDB->quote($ilUser->getId(), "integer").
5082  " AND page_id = ".$ilDB->quote($this->getId(), "integer").
5083  " AND parent_type = ".$ilDB->quote($this->getParentType(), "text")
5084  );
5085 
5086  $set = $ilDB->query("SELECT edit_lock_user FROM page_object ".
5087  " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
5088  " AND parent_type = ".$ilDB->quote($this->getParentType(), "text")
5089  );
5090  $rec = $ilDB->fetchAssoc($set);
5091  if ($rec["edit_lock_user"] != $ilUser->getId())
5092  {
5093  return false;
5094  }
5095  }
5096 
5097  return true;
5098  }
5099 
5105  function getEditLockInfo()
5106  {
5107  global $ilDB;
5108 
5109  $aset = new ilSetting("adve");
5110  $min = (int) $aset->get("block_mode_minutes");
5111 
5112  $set = $ilDB->query("SELECT edit_lock_user, edit_lock_ts FROM page_object ".
5113  " WHERE page_id = ".$ilDB->quote($this->getId(), "integer").
5114  " AND parent_type = ".$ilDB->quote($this->getParentType(), "text")
5115  );
5116  $rec = $ilDB->fetchAssoc($set);
5117  $rec["edit_lock_until"] = $rec["edit_lock_ts"] + $min * 60;
5118 
5119  return $rec;
5120  }
5121 
5134  public static function truncateHTML($a_text, $a_length = 100, $a_ending = '...', $a_exact = false, $a_consider_html = true)
5135  {
5136  include_once "Services/Utilities/classes/class.ilStr.php";
5137 
5138  if ($a_consider_html)
5139  {
5140  // if the plain text is shorter than the maximum length, return the whole text
5141  if(strlen(preg_replace('/<.*?>/', '', $a_text)) <= $a_length)
5142  {
5143  return $a_text;
5144  }
5145 
5146  // splits all html-tags to scanable lines
5147  $total_length = strlen($a_ending);
5148  $open_tags = array();
5149  $truncate = '';
5150  preg_match_all('/(<.+?>)?([^<>]*)/s', $a_text, $lines, PREG_SET_ORDER);
5151  foreach($lines as $line_matchings)
5152  {
5153  // if there is any html-tag in this line, handle it and add it (uncounted) to the output
5154  if(!empty($line_matchings[1]))
5155  {
5156  // if it's an "empty element" with or without xhtml-conform closing slash
5157  if(preg_match('/^<(\s*.+?\/\s*|\s*(img|br|input|hr|area|base|basefont|col|frame|isindex|link|meta|param)(\s.+?)?)>$/is', $line_matchings[1]))
5158  {
5159  // do nothing
5160  }
5161  // if tag is a closing tag
5162  else if(preg_match('/^<\s*\/([^\s]+?)\s*>$/s', $line_matchings[1], $tag_matchings))
5163  {
5164  // delete tag from $open_tags list
5165  $pos = array_search($tag_matchings[1], $open_tags);
5166  if ($pos !== false)
5167  {
5168  unset($open_tags[$pos]);
5169  }
5170  }
5171  // if tag is an opening tag
5172  else if (preg_match('/^<\s*([^\s>!]+).*?>$/s', $line_matchings[1], $tag_matchings))
5173  {
5174  // add tag to the beginning of $open_tags list
5175  array_unshift($open_tags, strtolower($tag_matchings[1]));
5176  }
5177  // add html-tag to $truncate'd text
5178  $truncate .= $line_matchings[1];
5179  }
5180 
5181  // calculate the length of the plain text part of the line; handle entities as one character
5182  $content_length = strlen(preg_replace('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|[0-9a-f]{1,6};/i', ' ', $line_matchings[2]));
5183  if($total_length+$content_length > $a_length)
5184  {
5185  // the number of characters which are left
5186  $left = $a_length - $total_length;
5187  $entities_length = 0;
5188  // search for html entities
5189  if(preg_match_all('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|[0-9a-f]{1,6};/i', $line_matchings[2], $entities, PREG_OFFSET_CAPTURE))
5190  {
5191  // calculate the real length of all entities in the legal range
5192  foreach($entities[0] as $entity)
5193  {
5194  if($entity[1]+1-$entities_length <= $left)
5195  {
5196  $left--;
5197  $entities_length += strlen($entity[0]);
5198  }
5199  else
5200  {
5201  // no more characters left
5202  break;
5203  }
5204  }
5205  }
5206 
5207  // $truncate .= substr($line_matchings[2], 0, $left+$entities_length);
5208  $truncate .= ilStr::shortenText($line_matchings[2], 0, $left+$entities_length);
5209 
5210  // maximum lenght is reached, so get off the loop
5211  break;
5212  }
5213  else
5214  {
5215  $truncate .= $line_matchings[2];
5216  $total_length += $content_length;
5217  }
5218 
5219  // if the maximum length is reached, get off the loop
5220  if($total_length >= $a_length)
5221  {
5222  break;
5223  }
5224  }
5225  }
5226  else
5227  {
5228  if(strlen($a_text) <= $a_length)
5229  {
5230  return $a_text;
5231  }
5232  else
5233  {
5234  // $truncate = substr($a_text, 0, $a_length - strlen($a_ending));
5235  $truncate = ilStr::shortenText($a_text, 0, $a_length - strlen($a_ending));
5236  }
5237  }
5238 
5239  // THIS IS BUGGY AS IT MIGHT BREAK AN OPEN TAG AT THE END
5240  if(!sizeof($open_tags))
5241  {
5242  // if the words shouldn't be cut in the middle...
5243  if (!$a_exact)
5244  {
5245  // ...search the last occurance of a space...
5246  $spacepos = strrpos($truncate, ' ');
5247  if($spacepos !== false)
5248  {
5249  // ...and cut the text in this position
5250  // $truncate = substr($truncate, 0, $spacepos);
5251  $truncate = ilStr::shortenText($truncate, 0, $spacepos);
5252  }
5253  }
5254  }
5255 
5256  // add the defined ending to the text
5257  $truncate .= $a_ending;
5258 
5259  if($a_consider_html)
5260  {
5261  // close all unclosed html-tags
5262  foreach($open_tags as $tag)
5263  {
5264  $truncate .= '</'.$tag.'>';
5265  }
5266  }
5267 
5268  return $truncate;
5269  }
5270 
5277  {
5278  return array();
5279  }
5280 
5288  static function getLastChangeByParent($a_parent_type, $a_parent_id, $a_lang = "")
5289  {
5290  global $ilDB;
5291 
5292  $and_lang = "";
5293  if ($a_lang != "")
5294  {
5295  $and_lang = " AND lang = ".$ilDB->quote($a_lang, "text");
5296  }
5297 
5298  $ilDB->setLimit(1);
5299  $q = "SELECT last_change FROM page_object ".
5300  " WHERE parent_id = ".$ilDB->quote($a_parent_id, "integer").
5301  " AND parent_type = ".$ilDB->quote($a_parent_type, "text").$and_lang.
5302  " ORDER BY last_change DESC";
5303 
5304  $set = $ilDB->query($q);
5305  $rec = $ilDB->fetchAssoc($set);
5306 
5307  return $rec["last_change"];
5308  }
5309 
5315  function getAllFileObjIds()
5316  {
5317  $file_obj_ids = array();
5318 
5319  // insert inst id file item identifier entries
5320  $xpc = xpath_new_context($this->dom);
5321  $path = "//FileItem/Identifier";
5322  $res = xpath_eval($xpc, $path);
5323  for($i = 0; $i < count($res->nodeset); $i++)
5324  {
5325  $file_obj_ids[] = $res->nodeset[$i]->get_attribute("Entry");
5326  }
5327  unset($xpc);
5328  return $file_obj_ids;
5329  }
5330 
5335  public function resolveResources($ref_mapping)
5336  {
5337  include_once("./Services/COPage/classes/class.ilPCResources.php");
5338  return ilPCResources::resolveResources($this, $ref_mapping);
5339  }
5340 
5341 
5342 
5343 }
5344 ?>
$files
Definition: add-vimline.php:18
static _exists($a_parent_type, $a_id, $a_lang="", $a_no_cache=false)
Checks whether page exists.
getLastUpdateOfIncludedElements()
Get last update of included elements (media objects and files).
static _lookupName($a_user_id)
lookup user name
xslt_create()
buildDom($a_force=false)
performAutomaticModifications()
Perform automatic modifications (may be overwritten by sub classes)
removeQuestions(&$temp_dom)
Remove questions from document.
appendXMLContent($a_xml)
append xml content to page setXMLContent must be called before and the same encoding must be used ...
stripHierIDs()
strip all hierarchical id attributes out of the dom tree
static shortenText($a_string, $a_start_pos, $a_num_bytes, $a_encoding='UTF-8')
Shorten text to the given number of bytes.
checkPCIds()
Check, whether (all) page content hashes are set.
increaseViewCnt()
Increase view cnt.
getAllPCIds()
Get all pc ids.
$error
Definition: Error.php:17
generatePcId($a_pc_ids=false)
Generate new pc id.
$target_arr
Definition: goto.php:49
ILIAS Setting Class.
static deliverData($a_data, $a_filename, $mime="application/octet-stream", $charset="")
deliver data for download via browser.
static incEdId($ed_id)
Increases an hierarchical editing id at lowest level (last number)
static _getMobsOfObject($a_type, $a_id, $a_usage_hist_nr=0, $a_lang="-")
get mobs of object
static _existsAndNotEmpty($a_parent_type, $a_id, $a_lang="-")
Checks whether page exists and is not empty (may return true on some empty pages) ...
updateFromXML()
Updates page object with current xml content.
$path
Definition: aliased.php:25
__beforeDelete()
Before deletion handler (internal).
releasePageLock()
Release page lock.
addFileSizes()
add file sizes
static getPCDefinitionByName($a_pc_name)
Get PC definition by name.
lookforhier($a_hier_id)
getInternalLinks($a_cnt_multiple=false)
get all internal links that are used within the page
$size
Definition: RandomTest.php:79
static _getMapAreasIntLinks($a_mob_id)
get all internal links of map areas of a mob
static _lookupType($a_obj_id, $a_lm_id=0)
Lookup type.
copyPageToTranslation($a_target_lang)
Copy page to translation.
const IL_CAL_DATETIME
getFO()
get fo page content
getLanguage()
Get language.
static _deleteAllUsages($a_type, $a_id, $a_usage_hist_nr=0, $a_lang="-")
static
needsImportParsing($a_parse="")
const ILIAS_VERSION_NUMERIC
__afterUpdate($a_domdoc, $a_xml, $a_creation=false, $a_empty=false)
After update event handler (internal).
setImportMode($a_val)
Set import mode.
deleteContentFromHierId($a_hid, $a_update=true)
delete content object with hierarchical id >= $a_hid
xpath_new_context($dom_document)
Class ilPCTable.
setActive($a_active)
set activation
static _exists($a_id, $a_reference=false, $a_type=null)
checks if an object exists in object_data
existsPCId($a_pc_id)
existsPCId
static sortHierIds($a_array)
Sort an array of Hier IDS in ascending order.
$_GET["client_id"]
$h
resolveIIMMediaAliases($a_mapping)
Resolve iim media aliases (in ilContObjParse)
getFirstColumnIds()
get ids of all first table columns
handleCopiedContent($a_dom, $a_self_ass=true, $a_clone_mobs=false)
Handle copied content.
static _after(ilDateTime $start, ilDateTime $end, $a_compare_field='', $a_tz='')
compare two dates and check start is after end This method does not consider tz offsets.
xslt_free(&$proc)
getMediaAliasElement($a_mob_id, $a_nr=1)
get complete media object (alias) element
create()
create new page (with current xml data)
static getPagesWithLinks($a_parent_type, $a_parent_id, $a_lang="-")
Get all pages for parent object that contain internal links.
setParagraphContent($a_hier_id, $a_content)
Set content of paragraph.
deleteContents($a_hids, $a_update=true, $a_self_ass=false)
Delete multiple content objects.
setActivationEnd($a_activationend)
Set Activation End.
static _before(ilDateTime $start, ilDateTime $end, $a_compare_field='', $a_tz='')
compare two dates and check start is before end This method does not consider tz offsets.
setActivationStart($a_activationstart)
Set Activation Start.
copyXmlContent($a_clone_mobs=false)
Copy content of page; replace page components with copies where necessary (e.g.
xpath_eval($xpath_context, $eval_str, $contextnode=null)
newIIMCopies($temp_dom)
Replaces media objects in interactive images with copies of the interactive images.
static getPCDefinitions()
Get PC definitions.
static getAllPages($a_parent_type, $a_parent_id, $a_lang="-")
Get all pages for parent object.
static getPageContributors($a_parent_type, $a_page_id, $a_lang="-")
Get all contributors for parent object.
send_paragraph($par_id, $filename)
static _resolveMapAreaLinks($a_mob_id)
resolve internal links of all media items of a media object
pasteContents($a_hier_id, $a_self_ass=false)
Paste contents from pc clipboard.
setShowActivationInfo($a_val)
Set show page activation info.
Class ilPCParagraph.
resolveIntLinks($a_link_map=null)
Resolves all internal link targets of the page, if targets are available (after import) ...
read()
Read page data.
getQuestionIds()
Get question ids.
getHistoryEntries()
Get History Entries.
static getLastChangeByParent($a_parent_type, $a_parent_id, $a_lang="")
Get all pages for parent object.
getDomDoc()
Get dom doc (php5 dom document)
Class ilMediaAliasItem.
static requirePCClassByName($a_name)
Get instance.
moveContentAfter($a_source, $a_target, $a_spcid="", $a_tpcid="")
move content object from position $a_source before position $a_target (both hierarchical content ids)...
checkForTag($a_content_tag, $a_hier_id, $a_pc_id="")
Get content node from dom.
registerOfflineHandler($handler)
const IL_CAL_UNIX
static _moveContentAfterHierId(&$a_source_page, &$a_target_page, $a_hid)
move content of hierarchical id >= $a_hid to other page
static sortArray($array, $a_array_sortby, $a_array_sortorder=0, $a_numeric=false, $a_keep_keys=false)
sortArray
static now()
Return current timestamp in Y-m-d H:i:s format.
getPageContentsHashes()
Get page contents hashes.
__afterHistoryEntry($a_old_domdoc, $a_old_content, $a_old_nr)
Before deletion handler (internal).
getContentObject($a_hier_id, $a_pc_id="")
Get a content object of the page.
handleRepositoryLinksOnCopy($a_mapping, $a_source_ref_id)
Handle repository links on copy process.
getFileItemIds()
get ids of all file items
global $ilCtrl
Definition: ilias.php:18
getRenderMd5()
Get Render MD5.
getXMLFromDom($a_incl_head=false, $a_append_mobs=false, $a_append_bib=false, $a_append_str="", $a_omit_pageobject_tag=false)
get xml content of page from dom (use this, if any changes are made to the document) ...
static getConfigInstance($a_parent_type)
Get page config instance.
static lookupParentId($a_id, $a_type)
Lookup parent id.
newMobCopies($temp_dom)
Replaces media objects with copies.
$a_type
Definition: workflow.php:93
moveIntLinks($a_from_to)
Move internal links from one destination to another.
setRenderedContent($a_renderedcontent)
Set Rendered Content.
compareVersion($a_left, $a_right)
Compares to revisions of the page.
static getNamePresentation($a_user_id, $a_user_image=false, $a_profile_link=false, $a_profile_back_link="", $a_force_first_lastname=false, $a_omit_login=false, $a_sortable=true, $a_return_data_array=false)
Default behaviour is:
addUpdateListener(&$a_object, $a_method, $a_parameters="")
collectMediaObjects($a_inline_only=true)
get all media objects, that are referenced and used within the page
static xml2output($a_text, $a_wysiwyg=false, $a_replace_lists=true)
Converts xml from DB to output in edit textarea.
__construct($a_id=0, $a_old_nr=0, $a_lang="-")
Constructor public.
moveContentBefore($a_source, $a_target, $a_spcid="", $a_tpcid="")
move content object from position $a_source before position $a_target (both hierarchical content ids)...
if(!is_array($argv)) $options
$mobs
static _existsAndNotEmpty($a_parent_type, $a_id, $a_lang="-")
checks whether page exists and is not empty (may return true on some empty pages) ...
getXMLContent($a_incl_head=false)
get xml content of page
static _lookupActive($a_id, $a_parent_type, $a_check_scheduled_activation=false, $a_lang="-")
lookup activation status
$a_content
Definition: workflow.php:94
static _writeParentId($a_parent_type, $a_pg_id, $a_par_id)
Write parent id.
beforePageContentUpdate($a_page_content)
Before page content update.
deleteInternalLinks()
Delete internal links.
static _writeActive($a_id, $a_parent_type, $a_active, $a_reset_scheduled_activation=true, $a_lang="-")
write activation status
getActive($a_check_scheduled_activation=false)
get activation
getLastChange()
Get Last Change.
insertContentNode(&$a_cont_node, $a_pos, $a_mode=IL_INSERT_AFTER, $a_pcid="")
insert a content node before/after a sibling or as first child of a parent
getListItemIds()
get ids of all list items
getInitialOpenedContent()
Get initial opened content.
resolveFileItems($a_mapping)
Resolve file items (after import)
static _lookupObjId($a_id)
date( 'd-M-Y', $objPHPExcel->getProperties() ->getCreated())
Class ilPageObject.
resolveQuestionReferences($a_mapping)
Resolve all quesion references (after import)
containsIntLink()
returns true, if page was marked as containing an intern link (via setContainsIntLink) (this method s...
static formatDate(ilDateTime $date)
Format a date public.
createFromXML()
Create new page object with current xml content.
setRenderedTime($a_renderedtime)
Set Rendered Time.
getRenderedContent()
Get Rendered Content.
static getParentObjectContributors($a_parent_type, $a_parent_id, $a_lang="-")
Get all contributors for parent object.
getImportMode()
Get import mode.
getActivationStart()
Get Activation Start.
Date and time handling
$ilUser
Definition: imgupload.php:18
redirection script todo: (a better solution should control the processing via a xml file) ...
setPageConfig($a_val)
Set page config object.
appendLangVarXML(&$xml, $var)
static getRecentChanges($a_parent_type, $a_parent_id, $a_period=30, $a_lang="")
Get recent pages changes for parent object.
insertContent(&$a_cont_obj, $a_pos, $a_mode=IL_INSERT_AFTER, $a_pcid="")
insert a content node before/after a sibling or as first child of a parent
Class ilObjMediaObject.
Unknown page content type exception.
static _handleImportRepositoryLinks($a_rep_import_id, $a_rep_type, $a_rep_ref_id)
Change targest of repository links.
getOfflineHandler()
Get offline handler.
getShowActivationInfo()
Get show page activation info.
setId($a_id)
set id
const IL_INSERT_AFTER
static _lookupImportId($a_obj_id)
static _getFilesOfObject($a_type, $a_id, $a_usage_hist_nr=0, $a_usage_lang="-")
get all files of an object
update($a_validate=true, $a_no_history=false)
update complete page content in db (dom xml content is used)
Create styles array
The data for the language used.
static _lookupType($a_id, $a_reference=false)
lookup object type
setRenderMd5($a_rendermd5)
Set Render MD5.
static _lookupContainsDeactivatedElements($a_id, $a_parent_type, $a_lang="-")
lookup whether page contains deactivated elements
static _isScheduledActivation($a_id, $a_parent_type, $a_lang="-")
Check whether page is activated by time schedule.
containsIntLinks($a_content)
Check whether content contains internal links.
static _instantiateQuestion($question_id)
deleteContentBeforeHierId($a_hid, $a_update=true)
delete content object with hierarchical id < $a_hid
getContentTemplates()
Get content templates.
insertPCIds()
Insert Page Content IDs.
getFirstRowIds()
get ids of all first table rows
getLanguageVariablesXML()
Get language variables as XML.
addHierIDs()
Add hierarchical ID (e.g.
getLastChangeUser()
Get last change user.
insertInstIntoIDs($a_inst, $a_res_ref_to_obj_id=true)
inserts installation id into ids (e.g.
static truncateHTML($a_text, $a_length=100, $a_ending='...', $a_exact=false, $a_consider_html=true)
Truncate (html) string.
saveInitialOpenedContent($a_type, $a_id, $a_target)
Save initial opened content.
saveStyleUsage($a_domdoc, $a_old_nr=0)
Save all style class/template usages.
setContainsQuestion($a_val)
Set contains question.
handleImportRepositoryLink($a_rep_import_id, $a_rep_type, $a_rep_ref_id)
afterConstructor()
After constructor.
static _lookupFileSize($a_id)
Lookups the file size of the file in bytes.
static _lookupActivationData($a_id, $a_parent_type, $a_lang="-")
Lookup activation data.
static getInstance($a_parent_type, $a_id=0, $a_old_nr=0, $a_lang="-")
Get page object instance.
$errors
static _getLastUpdateOfObjects($a_objs)
Get last update for a set of media objects.
getDom()
Deprecated php4DomDocument.
setLastChange($a_lastchange)
Set Last Change.
getHistoryEntry($a_old_nr)
Get History Entry.
getEditLockInfo()
Get edit lock info.
bbCode2XML(&$a_content)
transforms bbCode to corresponding xml
setLanguage($a_val)
Set language.
$lm_set
global $l
Definition: afr.php:30
setXMLContent($a_xml, $a_encoding="UTF-8")
set xml content of page, start with <PageObject...>, end with </PageObject>, comply with ILIAS DTD...
$ref_id
Definition: sahs_server.php:39
newQuestionCopies(&$temp_dom)
Replaces existing question content elements with new copies.
setLastChangeUser($a_val)
Set last change user.
writeRenderedContent($a_content, $a_md5)
Write rendered content.
initPageConfig()
Init page config.
getPageConfig()
Get page config object.
global $lng
Definition: privfeed.php:17
static lookupTranslations($a_parent_type, $a_id)
Lookup translations.
getMultimediaXML()
get a xml string that contains all media object elements, that are referenced by any media alias in t...
static preloadActivationDataByParentId($a_parent_id)
Preload activation data by Parent Id.
containsDeactivatedElements($a_content)
Check whether content contains deactivated elements.
global $ilDB
resolveMediaAliases($a_mapping, $a_reuse_existing_by_import=false)
Resolve media aliases (after import)
getEditLock()
Get page lock.
$ret
Definition: parser.php:6
setContainsIntLink($a_contains_link)
lm parser set this flag to true, if the page contains intern links (this method should only be called...
switchEnableMultiple($a_hids, $a_update=true, $a_self_ass=false)
(De-)activate elements
copyContents($a_hids)
Copy contents to clipboard.
getHistoryInfo($a_nr)
Get information about a history entry, its predecessor and its successor.
const IL_MODE_OUTPUT
countPageContents()
Remove questions from document.
static getLogger($a_component_id)
Get component logger.
domxml_open_mem($str, $mode=0, &$error=NULL)
Add data(end) time
Method that wraps PHPs time in order to allow simulations with the workflow.
getHierIds()
get all hierarchical ids
Class ilPCMediaObject.
saveInternalLinks($a_domdoc)
save internal links of page
afterUpdate()
After update.
getRenderedTime()
Get Rendered Time.
& getContentNode($a_hier_id, $a_pc_id="")
Get content node from dom.
getActivationEnd()
Get Activation End.
static setAction($a_action)
resolveResources($ref_mapping)
Resolve resources.
static getNewPages($a_parent_type, $a_parent_id, $a_lang="-")
Get new pages.
static deleteNewsOfContext($a_context_obj_id, $a_context_obj_type, $a_context_sub_obj_id=0, $a_context_sub_obj_type="")
Delete all news of a context.
getHierIdsForPCIds($a_pc_ids)
Get hier ids for a set of pc ids.
$_POST["username"]
$params
Definition: example_049.php:96
copy($a_id, $a_parent_type="", $a_parent_id=0, $a_clone_mobs=false)
Copy page.
static resolveResources(ilPageObject $page, $ref_mappings)
Resolve resources.
Extension of ilPageObject for learning modules.
getContainsQuestion()
Get contains question.
getAllFileObjIds()
Get all file object ids.
getParentType()
Get parent type.
deleteStyleUsages($a_old_nr=0)
Delete style usages.
const IL_INSERT_CHILD
validateDom()
Validate the page content agains page DTD.
const IL_INSERT_BEFORE
cutContents($a_hids)
Copy contents to clipboard and cut them from the page.
deleteContent($a_hid, $a_update=true, $a_pcid="")
delete content object with hierarchical id $a_hid
Class ilPCDataTable.
addChangeDivClasses($a_hashes)