ILIAS  Release_3_10_x_branch Revision 61812
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.ilPageObject.php
Go to the documentation of this file.
1 <?php
2 /*
3  +-----------------------------------------------------------------------------+
4  | ILIAS open source |
5  +-----------------------------------------------------------------------------+
6  | Copyright (c) 1998-2008 ILIAS open source, University of Cologne |
7  | |
8  | This program is free software; you can redistribute it and/or |
9  | modify it under the terms of the GNU General Public License |
10  | as published by the Free Software Foundation; either version 2 |
11  | of the License, or (at your option) any later version. |
12  | |
13  | This program is distributed in the hope that it will be useful, |
14  | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16  | GNU General Public License for more details. |
17  | |
18  | You should have received a copy of the GNU General Public License |
19  | along with this program; if not, write to the Free Software |
20  | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
21  +-----------------------------------------------------------------------------+
22 */
23 
24 require_once("./Services/COPage/classes/class.ilPageContent.php");
25 require_once("./Services/COPage/classes/class.ilPCParagraph.php");
26 require_once("./Services/COPage/syntax_highlight/php/Beautifier/Init.php");
27 require_once("./Services/COPage/syntax_highlight/php/Output/Output_css.php");
28 
29 
30 define("IL_INSERT_BEFORE", 0);
31 define("IL_INSERT_AFTER", 1);
32 define("IL_INSERT_CHILD", 2);
33 
34 define ("IL_CHAPTER_TITLE", "st_title");
35 define ("IL_PAGE_TITLE", "pg_title");
36 define ("IL_NO_HEADER", "none");
37 
53 {
54  var $id;
55  var $ilias;
56  var $dom;
57  var $xml;
58  var $encoding;
59  var $node;
60  var $cur_dtd = "ilias_pg_3_10.dtd";
70 
75  function ilPageObject($a_parent_type, $a_id = 0, $a_old_nr = 0, $a_halt = true)
76  {
77  global $ilias;
78 
79  $this->parent_type = $a_parent_type;
80  $this->id = $a_id;
81  $this->ilias =& $ilias;
82 
83  $this->contains_int_link = false;
84  $this->needs_parsing = false;
85  $this->update_listeners = array();
86  $this->update_listener_cnt = 0;
87  $this->dom_builded = false;
88  $this->halt_on_error = $a_halt;
89  $this->page_not_found = false;
90  $this->old_nr = $a_old_nr;
91  $this->encoding = "UTF-8";
92  $this->id_elements =
93  array("PageContent", "TableRow", "TableData", "ListItem", "FileItem",
94  "Section", "Tab");
95 
96  if($a_id != 0)
97  {
98  $this->read();
99  }
100  }
101 
102  function haltOnError($a_halt)
103  {
104  $this->halt_on_error = $a_halt;
105  }
106 
112  function setRenderMd5($a_rendermd5)
113  {
114  $this->rendermd5 = $a_rendermd5;
115  }
116 
122  function getRenderMd5()
123  {
124  return $this->rendermd5;
125  }
126 
132  function setRenderedContent($a_renderedcontent)
133  {
134  $this->renderedcontent = $a_renderedcontent;
135  }
136 
143  {
144  return $this->renderedcontent;
145  }
146 
152  function setRenderedTime($a_renderedtime)
153  {
154  $this->renderedtime = $a_renderedtime;
155  }
156 
162  function getRenderedTime()
163  {
164  return $this->renderedtime;
165  }
166 
172  function setLastChange($a_lastchange)
173  {
174  $this->lastchange = $a_lastchange;
175  }
176 
182  function getLastChange()
183  {
184  return $this->lastchange;
185  }
186 
190  function read()
191  {
192  global $ilBench, $ilDB;
193 
194  $ilBench->start("ContentPresentation", "ilPageObject_read");
195  if ($this->old_nr == 0)
196  {
197  $query = "SELECT * FROM page_object WHERE page_id = ".$ilDB->quote($this->id)." ".
198  "AND parent_type=".$ilDB->quote($this->getParentType());
199  $pg_set = $this->ilias->db->query($query);
200  $this->page_record = $pg_set->fetchRow(DB_FETCHMODE_ASSOC);
201  }
202  else
203  {
204  $query = "SELECT * FROM page_history WHERE page_id = ".$ilDB->quote($this->id)." ".
205  "AND parent_type=".$ilDB->quote($this->getParentType()).
206  " AND nr = ".$ilDB->quote($this->old_nr);
207  $pg_set = $this->ilias->db->query($query);
208  $this->page_record = $pg_set->fetchRow(DB_FETCHMODE_ASSOC);
209  }
210  if (!$this->page_record)
211  {
212  if ($this->halt_on_error)
213  {
214  echo "Error: Page ".$this->id." is not in database".
215  " (parent type ".$this->getParentType().")."; exit;
216  }
217  else
218  {
219  $this->page_not_found = true;
220  return;
221  }
222  }
223  $this->xml = $this->page_record["content"];
224  $this->setParentId($this->page_record["parent_id"]);
225  $this->last_change_user = $this->page_record["last_change_user"];
226  $this->create_user = $this->page_record["create_user"];
227  $this->setRenderedContent($this->page_record["rendered_content"]);
228  $this->setRenderMd5($this->page_record["render_md5"]);
229  $this->setRenderedTime($this->page_record["rendered_time"]);
230  $this->setLastChange($this->page_record["last_change"]);
231 
232  $ilBench->stop("ContentPresentation", "ilPageObject_read");
233  }
234 
241  function _exists($a_parent_type, $a_id)
242  {
243  global $ilDB;
244 
245  $query = "SELECT * FROM page_object WHERE page_id = ".$ilDB->quote($a_id)." ".
246  "AND parent_type= ".$ilDB->quote($a_parent_type);
247 
248  $set = $ilDB->query($query);
249  if ($row = $set->fetchRow(DB_FETCHMODE_ASSOC))
250  {
251  return true;
252  }
253  else
254  {
255  return false;
256  }
257  }
258 
259 
260  function buildDom($a_force = false)
261  {
262  global $ilBench;
263 
264  if ($this->dom_builded && !$a_force)
265  {
266  return;
267  }
268 
269 //echo "\n<br>buildDomWith:".$this->getId().":xml:".$this->getXMLContent(true).":<br>";
270 
271  $ilBench->start("ContentPresentation", "ilPageObject_buildDom");
272  $this->dom = @domxml_open_mem($this->getXMLContent(true), DOMXML_LOAD_VALIDATING, $error);
273  $ilBench->stop("ContentPresentation", "ilPageObject_buildDom");
274 
275  $xpc = xpath_new_context($this->dom);
276  $path = "//PageObject";
277  $res =& xpath_eval($xpc, $path);
278  if (count($res->nodeset) == 1)
279  {
280  $this->node =& $res->nodeset[0];
281  }
282 
283  if (empty($error))
284  {
285  $this->dom_builded = true;
286  return true;
287  }
288  else
289  {
290  return $error;
291  }
292  }
293 
294  function freeDom()
295  {
296  //$this->dom->free();
297  unset($this->dom);
298  }
299 
300  function &getDom()
301  {
302  return $this->dom;
303  }
304 
308  function setId($a_id)
309  {
310  $this->id = $a_id;
311  }
312 
313  function getId()
314  {
315  return $this->id;
316  }
317 
318  function setParentId($a_id)
319  {
320  $this->parent_id = $a_id;
321  }
322 
323  function getParentId()
324  {
325  return $this->parent_id;
326  }
327 
328  function setParentType($a_type)
329  {
330  $this->parent_type = $a_type;
331  }
332 
333  function getParentType()
334  {
335  return $this->parent_type;
336  }
337 
338  function addUpdateListener(&$a_object, $a_method, $a_parameters = "")
339  {
341  $this->update_listeners[$cnt]["object"] =& $a_object;
342  $this->update_listeners[$cnt]["method"] = $a_method;
343  $this->update_listeners[$cnt]["parameters"] = $a_parameters;
344  $this->update_listener_cnt++;
345  }
346 
348  {
349  for($i=0; $i<$this->update_listener_cnt; $i++)
350  {
351  $object =& $this->update_listeners[$i]["object"];
352  $method = $this->update_listeners[$i]["method"];
353  $parameters = $this->update_listeners[$i]["parameters"];
354  $object->$method($parameters);
355  }
356  }
357 
358  function &getContentObject($a_hier_id, $a_pc_id = "")
359  {
360 //echo ":".$a_hier_id.":";
361 //echo "Content:".htmlentities($this->getXMLFromDOM()).":<br>";
362 //echo "ilPageObject::getContentObject:hierid:".$a_hier_id.":<br>";
363  $cont_node =& $this->getContentNode($a_hier_id, $a_pc_id);
364 //echo "ilPageObject::getContentObject:nodename:".$cont_node->node_name().":<br>";
365  if (!is_object($cont_node))
366  {
367  return false;
368  }
369  switch($cont_node->node_name())
370  {
371  case "PageContent":
372  $child_node =& $cont_node->first_child();
373 //echo "<br>nodename:".$child_node->node_name();
374  switch($child_node->node_name())
375  {
376  case "Paragraph":
377  require_once("./Services/COPage/classes/class.ilPCParagraph.php");
378  $par =& new ilPCParagraph($this->dom);
379  $par->setNode($cont_node);
380  $par->setHierId($a_hier_id);
381  $par->setPcId($a_pc_id);
382  return $par;
383 
384  case "Table":
385  if ($child_node->get_attribute("DataTable") == "y")
386  {
387  require_once("./Services/COPage/classes/class.ilPCDataTable.php");
388  $tab =& new ilPCDataTable($this->dom);
389  $tab->setNode($cont_node);
390  $tab->setHierId($a_hier_id);
391  }
392  else
393  {
394  require_once("./Services/COPage/classes/class.ilPCTable.php");
395  $tab =& new ilPCTable($this->dom);
396  $tab->setNode($cont_node);
397  $tab->setHierId($a_hier_id);
398  }
399  $tab->setPcId($a_pc_id);
400  return $tab;
401 
402  case "MediaObject":
403 if ($_GET["pgEdMediaMode"] != "") {echo "ilPageObject::error media"; exit;}
404 
405  //require_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
406  require_once("./Services/COPage/classes/class.ilPCMediaObject.php");
407 
408  $mal_node =& $child_node->first_child();
409 //echo "ilPageObject::getContentObject:nodename:".$mal_node->node_name().":<br>";
410  $id_arr = explode("_", $mal_node->get_attribute("OriginId"));
411  $mob_id = $id_arr[count($id_arr) - 1];
412 
413  // allow deletion of non-existing media objects
414  if (!ilObject::_exists($mob_id) && in_array("delete", $_POST))
415  {
416  $mob_id = 0;
417  }
418 
419  //$mob =& new ilObjMediaObject($mob_id);
420  $mob = new ilPCMediaObject($this->dom);
421  $mob->readMediaObject($mob_id);
422 
423  //$mob->setDom($this->dom);
424  $mob->setNode($cont_node);
425  $mob->setHierId($a_hier_id);
426  $mob->setPcId($a_pc_id);
427  return $mob;
428 
429  case "List":
430  require_once("./Services/COPage/classes/class.ilPCList.php");
431  $list = new ilPCList($this->dom);
432  $list->setNode($cont_node);
433  $list->setHierId($a_hier_id);
434  $list->setPcId($a_pc_id);
435  return $list;
436 
437  case "FileList":
438  require_once("./Services/COPage/classes/class.ilPCFileList.php");
439  $file_list = new ilPCFileList($this->dom);
440  $file_list->setNode($cont_node);
441  $file_list->setHierId($a_hier_id);
442  $file_list->setPcId($a_pc_id);
443  return $file_list;
444 
445  // note: assessment handling is forwarded to assessment gui classes
446  case "Question":
447  require_once("./Services/COPage/classes/class.ilPCQuestion.php");
448  $pc_question = new ilPCQuestion($this->dom);
449  $pc_question->setNode($cont_node);
450  $pc_question->setHierId($a_hier_id);
451  $pc_question->setPcId($a_pc_id);
452  return $pc_question;
453 
454  case "Section":
455  require_once("./Services/COPage/classes/class.ilPCSection.php");
456  $sec = new ilPCSection($this->dom);
457  $sec->setNode($cont_node);
458  $sec->setHierId($a_hier_id);
459  $sec->setPcId($a_pc_id);
460  return $sec;
461 
462  case "Resources":
463  require_once("./Services/COPage/classes/class.ilPCResources.php");
464  $res = new ilPCResources($this->dom);
465  $res->setNode($cont_node);
466  $res->setHierId($a_hier_id);
467  $res->setPcId($a_pc_id);
468  return $res;
469 
470  case "Map":
471  require_once("./Services/COPage/classes/class.ilPCMap.php");
472  $map = new ilPCMap($this->dom);
473  $map->setNode($cont_node);
474  $map->setHierId($a_hier_id);
475  $map->setPcId($a_pc_id);
476  return $map;
477 
478  case "Tabs":
479  require_once("./Services/COPage/classes/class.ilPCTabs.php");
480  $map = new ilPCTabs($this->dom);
481  $map->setNode($cont_node);
482  $map->setHierId($a_hier_id);
483  $map->setPcId($a_pc_id);
484  return $map;
485 
486  case "Plugged":
487  require_once("./Services/COPage/classes/class.ilPCPlugged.php");
488  $plugged = new ilPCPlugged($this->dom);
489  $plugged->setNode($cont_node);
490  $plugged->setHierId($a_hier_id);
491  $plugged->setPcId($a_pc_id);
492  return $plugged;
493 
494  }
495  break;
496 
497  case "TableData":
498  require_once("./Services/COPage/classes/class.ilPCTableData.php");
499  $td =& new ilPCTableData($this->dom);
500  $td->setNode($cont_node);
501  $td->setHierId($a_hier_id);
502  return $td;
503 
504  case "ListItem":
505  require_once("./Services/COPage/classes/class.ilPCListItem.php");
506  $td =& new ilPCListItem($this->dom);
507  $td->setNode($cont_node);
508  $td->setHierId($a_hier_id);
509  return $td;
510 
511  case "FileItem":
512  require_once("./Services/COPage/classes/class.ilPCFileItem.php");
513  $file_item =& new ilPCFileItem($this->dom);
514  $file_item->setNode($cont_node);
515  $file_item->setHierId($a_hier_id);
516  return $file_item;
517 
518  case "Tab":
519  require_once("./Services/COPage/classes/class.ilPCTab.php");
520  $tab =& new ilPCTab($this->dom);
521  $tab->setNode($cont_node);
522  $tab->setHierId($a_hier_id);
523  return $file_item;
524 
525  }
526  }
527 
528  function &getContentNode($a_hier_id, $a_pc_id = "")
529  {
530  $xpc = xpath_new_context($this->dom);
531  if($a_hier_id == "pg")
532  {
533  return $this->node;
534  }
535  else
536  {
537  // get per pc id
538  if ($a_pc_id != "")
539  {
540  $path = "//*[@PCID = '$a_pc_id']";
541  $res =& xpath_eval($xpc, $path);
542  if (count($res->nodeset) == 1)
543  {
544  $cont_node =& $res->nodeset[0];
545  return $cont_node;
546  }
547  }
548 
549  // fall back to hier id
550  $path = "//*[@HierId = '$a_hier_id']";
551  $res =& xpath_eval($xpc, $path);
552  if (count($res->nodeset) == 1)
553  {
554  $cont_node =& $res->nodeset[0];
555  return $cont_node;
556  }
557  }
558  }
559 
560  // only for test purposes
561  function lookforhier($a_hier_id)
562  {
563  $xpc = xpath_new_context($this->dom);
564  $path = "//*[@HierId = '$a_hier_id']";
565  $res =& xpath_eval($xpc, $path);
566  if (count($res->nodeset) == 1)
567  return "YES";
568  else
569  return "NO";
570  }
571 
572 
573  function &getNode()
574  {
575  return $this->node;
576  }
577 
578 
587  function setXMLContent($a_xml, $a_encoding = "UTF-8")
588  {
589  $this->encoding = $a_encoding;
590  $this->xml = $a_xml;
591  }
592 
599  function appendXMLContent($a_xml)
600  {
601  $this->xml.= $a_xml;
602  }
603 
604 
608  function getXMLContent($a_incl_head = false)
609  {
610  // build full http path for XML DOCTYPE header.
611  // Under windows a relative path doesn't work :-(
612  if($a_incl_head)
613  {
614 //echo "+".$this->encoding."+";
615  $enc_str = (!empty($this->encoding))
616  ? "encoding=\"".$this->encoding."\""
617  : "";
618  return "<?xml version=\"1.0\" $enc_str ?>".
619  "<!DOCTYPE PageObject SYSTEM \"".ILIAS_ABSOLUTE_PATH."/xml/".$this->cur_dtd."\">".
620  $this->xml;
621  }
622  else
623  {
624  return $this->xml;
625  }
626  }
627 
632  function getXMLFromDom($a_incl_head = false, $a_append_mobs = false, $a_append_bib = false,
633  $a_append_str = "", $a_omit_pageobject_tag = false)
634  {
635  if ($a_incl_head)
636  {
637 //echo "\n<br>#".$this->encoding."#";
638  return $this->dom->dump_mem(0, $this->encoding);
639  }
640  else
641  {
642  // append multimedia object elements
643  if ($a_append_mobs || $a_append_bib || $a_append_link_info)
644  {
645  $mobs = "";
646  $bibs = "";
647  if ($a_append_mobs)
648  {
649  $mobs =& $this->getMultimediaXML();
650  }
651  if ($a_append_bib)
652  {
653  $bibs =& $this->getBibliographyXML();
654  }
655  $trans =& $this->getLanguageVariablesXML();
656  return "<dummy>".$this->dom->dump_node($this->node).$mobs.$bibs.$trans.$a_append_str."</dummy>";
657  }
658  else
659  {
660  if (is_object($this->dom))
661  {
662  if ($a_omit_pageobject_tag)
663  {
664  $xml = "";
665  $childs =& $this->node->child_nodes();
666  for($i = 0; $i < count($childs); $i++)
667  {
668  $xml.= $this->dom->dump_node($childs[$i]);
669  }
670  return $xml;
671  }
672  else
673  {
674  $xml = $this->dom->dump_mem(0, $this->encoding);
675  $xml = eregi_replace("<\?xml[^>]*>","",$xml);
676  $xml = eregi_replace("<!DOCTYPE[^>]*>","",$xml);
677 
678  return $xml;
679 
680  // don't use dump_node. This gives always entities.
681  //return $this->dom->dump_node($this->node);
682  }
683  }
684  else
685  {
686  return "";
687  }
688  }
689  }
690  }
691 
696  {
697  global $lng;
698 
699  $xml = "<LVs>";
700  $lang_vars = array("ed_insert_par", "ed_insert_code",
701  "ed_insert_dtable", "ed_insert_atable", "ed_insert_media", "ed_insert_list",
702  "ed_insert_filelist", "ed_paste_clip", "ed_edit", "ed_insert_section",
703  "ed_edit_prop","ed_edit_data", "ed_delete", "ed_moveafter", "ed_movebefore",
704  "ed_go", "ed_new_row_after", "ed_new_row_before",
705  "ed_new_col_after", "ed_new_col_before", "ed_delete_col",
706  "ed_delete_row", "ed_class", "ed_width", "ed_align_left",
707  "ed_align_right", "ed_align_center", "ed_align_left_float",
708  "ed_align_right_float", "ed_delete_item", "ed_new_item_before",
709  "ed_new_item_after", "ed_copy_clip", "please_select", "ed_split_page",
710  "ed_item_up", "ed_item_down", "ed_row_up", "ed_row_down",
711  "ed_col_left", "ed_col_right", "ed_split_page_next","ed_enable",
712  "de_activate", "ed_insert_repobj", "ed_insert_map", "ed_insert_tabs");
713 
714  foreach ($lang_vars as $lang_var)
715  {
716  $this->appendLangVarXML($xml, $lang_var);
717  }
718 
719  $xml.= "</LVs>";
720 
721  return $xml;
722  }
723 
724  function appendLangVarXML(&$xml, $var)
725  {
726  global $lng;
727 
728  $xml.= "<LV name=\"$var\" value=\"".$lng->txt("cont_".$var)."\"/>";
729  }
730 
732  {
733  $xpc = xpath_new_context($this->dom);
734  $path = "//Paragraph[1]";
735  $res =& xpath_eval($xpc, $path);
736  if (count($res->nodeset) > 0)
737  {
738  $cont_node =& $res->nodeset[0]->parent_node();
739  $par =& new ilPCParagraph($this->dom);
740  $par->setNode($cont_node);
741  return $par->getText();
742  }
743  else
744  {
745  return "";
746  }
747  }
748 
755  function setParagraphContent($a_hier_id, $a_content)
756  {
757  $node = $this->getContentNode($a_hier_id);
758  if (is_object($node))
759  {
760  $node->set_content($a_content);
761  }
762  }
763 
764 
773  function setContainsIntLink($a_contains_link)
774  {
775  $this->contains_int_link = $a_contains_link;
776  }
777 
782  function containsIntLink()
783  {
785  }
786 
787  function needsImportParsing($a_parse = "")
788  {
789 
790  if ($a_parse === true)
791  {
792  $this->needs_parsing = true;
793  }
794  if ($a_parse === false)
795  {
796  $this->needs_parsing = false;
797  }
798  return $this->needs_parsing;
799  }
800 
806  {
807  global $ilias, $ilDB;
808 
809  // todo: access to $_GET and $_POST variables is not
810  // allowed in non GUI classes!
811  //
812  // access to db table object_reference is not allowed here!
813  $r = $ilias->db->query("SELECT * FROM object_reference WHERE ref_id=".
814  $ilDB->quote($_GET["ref_id"]));
815  $row = $r->fetchRow(DB_FETCHMODE_ASSOC);
816 
817  include_once("./classes/class.ilNestedSetXML.php");
818  $nested = new ilNestedSetXML();
819  $bibs_xml = $nested->export($row["obj_id"], "bib");
820 
821  return $bibs_xml;
822  }
823 
824 
829  function collectMediaObjects($a_inline_only = true)
830  {
831 //echo htmlentities($this->getXMLFromDom());
832  // determine all media aliases of the page
833  $xpc = xpath_new_context($this->dom);
834  $path = "//MediaObject/MediaAlias";
835  $res =& xpath_eval($xpc, $path);
836  $mob_ids = array();
837  for($i = 0; $i < count($res->nodeset); $i++)
838  {
839  $id_arr = explode("_", $res->nodeset[$i]->get_attribute("OriginId"));
840  $mob_id = $id_arr[count($id_arr) - 1];
841  $mob_ids[$mob_id] = $mob_id;
842  }
843 
844  // determine all inline internal media links
845  $xpc = xpath_new_context($this->dom);
846  $path = "//IntLink[@Type = 'MediaObject']";
847  $res =& xpath_eval($xpc, $path);
848 
849  for($i = 0; $i < count($res->nodeset); $i++)
850  {
851  if (($res->nodeset[$i]->get_attribute("TargetFrame") == "") ||
852  (!$a_inline_only))
853  {
854  $target = $res->nodeset[$i]->get_attribute("Target");
855  $id_arr = explode("_", $target);
856  if (($id_arr[1] == IL_INST_ID) ||
857  (substr($target, 0, 4) == "il__"))
858  {
859  $mob_id = $id_arr[count($id_arr) - 1];
860  if (ilObject::_exists($mob_id))
861  {
862  $mob_ids[$mob_id] = $mob_id;
863  }
864  }
865  }
866  }
867 
868  return $mob_ids;
869  }
870 
871 
875  function getInternalLinks()
876  {
877  // get all internal links of the page
878  $xpc = xpath_new_context($this->dom);
879  $path = "//IntLink";
880  $res =& xpath_eval($xpc, $path);
881 
882  $links = array();
883  for($i = 0; $i < count($res->nodeset); $i++)
884  {
885  $target = $res->nodeset[$i]->get_attribute("Target");
886  $type = $res->nodeset[$i]->get_attribute("Type");
887  $targetframe = $res->nodeset[$i]->get_attribute("TargetFrame");
888  $links[$target.":".$type.":".$targetframe] =
889  array("Target" => $target, "Type" => $type,
890  "TargetFrame" => $targetframe);
891 
892  // get links (image map areas) for inline media objects
893  if ($type == "MediaObject" && $targetframe == "")
894  {
895  if (substr($target, 0, 4) =="il__")
896  {
897  $id_arr = explode("_", $target);
898  $id = $id_arr[count($id_arr) - 1];
899 
901  foreach($med_links as $key => $med_link)
902  {
903  $links[$key] = $med_link;
904  }
905  }
906 
907  }
908 //echo "<br>-:".$target.":".$type.":".$targetframe.":-";
909  }
910  unset($xpc);
911 
912  // get all media aliases
913  $xpc = xpath_new_context($this->dom);
914  $path = "//MediaAlias";
915  $res =& xpath_eval($xpc, $path);
916 
917  require_once("Services/MediaObjects/classes/class.ilMediaItem.php");
918  for($i = 0; $i < count($res->nodeset); $i++)
919  {
920  $oid = $res->nodeset[$i]->get_attribute("OriginId");
921  if (substr($oid, 0, 4) =="il__")
922  {
923  $id_arr = explode("_", $oid);
924  $id = $id_arr[count($id_arr) - 1];
925 
927  foreach($med_links as $key => $med_link)
928  {
929  $links[$key] = $med_link;
930  }
931  }
932  }
933  unset($xpc);
934 
935  return $links;
936  }
937 
941  function collectFileItems($a_xml = "")
942  {
943 //echo "<br>PageObject::collectFileItems[".$this->getId()."]";
944  // determine all media aliases of the page
945  if ($a_xml == "")
946  {
947  $xpc = xpath_new_context($this->dom);
948  $path = "//FileItem/Identifier";
949  $res =& xpath_eval($xpc, $path);
950  }
951  else
952  {
953  $doc = domxml_open_mem($a_xml);
954  $xpc = xpath_new_context($doc);
955  $path = "//FileItem/Identifier";
956  $res =& xpath_eval($xpc, $path);
957  }
958  $file_ids = array();
959  for($i = 0; $i < count($res->nodeset); $i++)
960  {
961  $id_arr = explode("_", $res->nodeset[$i]->get_attribute("Entry"));
962  $file_id = $id_arr[count($id_arr) - 1];
963  $file_ids[$file_id] = $file_id;
964  }
965 
966  return $file_ids;
967  }
968 
973  function getMultimediaXML()
974  {
975  $mob_ids = $this->collectMediaObjects();
976 
977  // get xml of corresponding media objects
978  $mobs_xml = "";
979  require_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
980  foreach($mob_ids as $mob_id => $dummy)
981  {
982  if (ilObject::_lookupType($mob_id) == "mob")
983  {
984  $mob_obj =& new ilObjMediaObject($mob_id);
985  $mobs_xml .= $mob_obj->getXML(IL_MODE_OUTPUT);
986  }
987  }
988  return $mobs_xml;
989  }
990 
994  function getMediaAliasElement($a_mob_id, $a_nr = 1)
995  {
996  $xpc = xpath_new_context($this->dom);
997  $path = "//MediaObject/MediaAlias[@OriginId='il__mob_$a_mob_id']";
998  $res =& xpath_eval($xpc, $path);
999  $mal_node =& $res->nodeset[$a_nr - 1];
1000  $mob_node =& $mal_node->parent_node();
1001 
1002  return $this->dom->dump_node($mob_node);
1003  }
1004 
1010  function validateDom()
1011  {
1012  $this->stripHierIDs();
1013  $this->dom->validate($error);
1014  return $error;
1015  }
1016 
1032  function addHierIDs()
1033  {
1034  $this->hier_ids = array();
1035  $this->first_row_ids = array();
1036  $this->first_col_ids = array();
1037  $this->list_item_ids = array();
1038  $this->file_item_ids = array();
1039 
1040  // set hierarchical ids for Paragraphs, Tables, TableRows and TableData elements
1041  $xpc = xpath_new_context($this->dom);
1042  //$path = "//Paragraph | //Table | //TableRow | //TableData";
1043 
1044  $sep = $path = "";
1045  foreach ($this->id_elements as $el)
1046  {
1047  $path.= $sep."//".$el;
1048  $sep = " | ";
1049  }
1050 
1051  $res =& xpath_eval($xpc, $path);
1052  for($i = 0; $i < count($res->nodeset); $i++)
1053  {
1054  $cnode = $res->nodeset[$i];
1055  $ctag = $cnode->node_name();
1056 
1057  // get hierarchical id of previous sibling
1058  $sib_hier_id = "";
1059  while($cnode =& $cnode->previous_sibling())
1060  {
1061  if (($cnode->node_type() == XML_ELEMENT_NODE)
1062  && $cnode->has_attribute("HierId"))
1063  {
1064  $sib_hier_id = $cnode->get_attribute("HierId");
1065  //$sib_hier_id = $id_attr->value();
1066  break;
1067  }
1068  }
1069 
1070  if ($sib_hier_id != "") // set id to sibling id "+ 1"
1071  {
1072  $node_hier_id = ilPageContent::incEdId($sib_hier_id);
1073  $res->nodeset[$i]->set_attribute("HierId", $node_hier_id);
1074  $this->hier_ids[] = $node_hier_id;
1075  if ($ctag == "TableData")
1076  {
1077  if (substr($par_hier_id,strlen($par_hier_id)-2) == "_1")
1078  {
1079  $this->first_row_ids[] = $node_hier_id;
1080  }
1081  }
1082  if ($ctag == "ListItem")
1083  {
1084  $this->list_item_ids[] = $node_hier_id;
1085  }
1086  if ($ctag == "FileItem")
1087  {
1088  $this->file_item_ids[] = $node_hier_id;
1089  }
1090  }
1091  else // no sibling -> node is first child
1092  {
1093  // get hierarchical id of next parent
1094  $cnode = $res->nodeset[$i];
1095  $par_hier_id = "";
1096  while($cnode =& $cnode->parent_node())
1097  {
1098  if (($cnode->node_type() == XML_ELEMENT_NODE)
1099  && $cnode->has_attribute("HierId"))
1100  {
1101  $par_hier_id = $cnode->get_attribute("HierId");
1102  //$par_hier_id = $id_attr->value();
1103  break;
1104  }
1105  }
1106 //echo "<br>par:".$par_hier_id." ($ctag)";
1107  if (($par_hier_id != "") && ($par_hier_id != "pg")) // set id to parent_id."_1"
1108  {
1109  $node_hier_id = $par_hier_id."_1";
1110  $res->nodeset[$i]->set_attribute("HierId", $node_hier_id);
1111  $this->hier_ids[] = $node_hier_id;
1112  if ($ctag == "TableData")
1113  {
1114  $this->first_col_ids[] = $node_hier_id;
1115  if (substr($par_hier_id,strlen($par_hier_id)-2) == "_1")
1116  {
1117  $this->first_row_ids[] = $node_hier_id;
1118  }
1119  }
1120  if ($ctag == "ListItem")
1121  {
1122  $this->list_item_ids[] = $node_hier_id;
1123  }
1124  if ($ctag == "FileItem")
1125  {
1126  $this->file_item_ids[] = $node_hier_id;
1127  }
1128 
1129  }
1130  else // no sibling, no parent -> first node
1131  {
1132  $node_hier_id = "1";
1133  $res->nodeset[$i]->set_attribute("HierId", $node_hier_id);
1134  $this->hier_ids[] = $node_hier_id;
1135  }
1136  }
1137  }
1138 
1139  // set special hierarchical id "pg" for pageobject
1140  $xpc = xpath_new_context($this->dom);
1141  $path = "//PageObject";
1142  $res =& xpath_eval($xpc, $path);
1143  for($i = 0; $i < count($res->nodeset); $i++) // should only be 1
1144  {
1145  $res->nodeset[$i]->set_attribute("HierId", "pg");
1146  $this->hier_ids[] = "pg";
1147  }
1148  unset($xpc);
1149  }
1150 
1154  function getHierIds()
1155  {
1156  return $this->hier_ids;
1157  }
1158 
1162  function getFirstRowIds()
1163  {
1164  return $this->first_row_ids;
1165  }
1166 
1171  {
1172  return $this->first_col_ids;
1173  }
1174 
1178  function getListItemIds()
1179  {
1180  return $this->list_item_ids;
1181  }
1182 
1186  function getFileItemIds()
1187  {
1188  return $this->file_item_ids;
1189  }
1190 
1194  function stripHierIDs()
1195  {
1196  if(is_object($this->dom))
1197  {
1198  $xpc = xpath_new_context($this->dom);
1199  $path = "//*[@HierId]";
1200  $res =& xpath_eval($xpc, $path);
1201  for($i = 0; $i < count($res->nodeset); $i++) // should only be 1
1202  {
1203  if ($res->nodeset[$i]->has_attribute("HierId"))
1204  {
1205  $res->nodeset[$i]->remove_attribute("HierId");
1206  }
1207  }
1208  unset($xpc);
1209  }
1210  }
1211 
1215  function addFileSizes()
1216  {
1217  $xpc = xpath_new_context($this->dom);
1218  $path = "//FileItem";
1219  $res =& xpath_eval($xpc, $path);
1220  for($i = 0; $i < count($res->nodeset); $i++)
1221  {
1222  $cnode =& $res->nodeset[$i];
1223  $size_node =& $this->dom->create_element("Size");
1224  $size_node =& $cnode->append_child($size_node);
1225 
1226  $childs =& $cnode->child_nodes();
1227  $size = "";
1228  for($j = 0; $j < count($childs); $j++)
1229  {
1230  if ($childs[$j]->node_name() == "Identifier")
1231  {
1232  if ($childs[$j]->has_attribute("Entry"))
1233  {
1234  $entry = $childs[$j]->get_attribute("Entry");
1235  $entry_arr = explode("_", $entry);
1236  $id = $entry_arr[count($entry_arr) - 1];
1237  require_once("./Modules/File/classes/class.ilObjFile.php");
1239  }
1240  }
1241  }
1242  $size_node->set_content($size);
1243  }
1244 
1245  unset($xpc);
1246  }
1247 
1252  function resolveIntLinks()
1253  {
1254  // resolve normal internal links
1255  $xpc = xpath_new_context($this->dom);
1256  $path = "//IntLink";
1257  $res =& xpath_eval($xpc, $path);
1258  for($i = 0; $i < count($res->nodeset); $i++)
1259  {
1260  $target = $res->nodeset[$i]->get_attribute("Target");
1261  $type = $res->nodeset[$i]->get_attribute("Type");
1262 
1263  $new_target = ilInternalLink::_getIdForImportId($type, $target);
1264  if ($new_target !== false)
1265  {
1266  $res->nodeset[$i]->set_attribute("Target", $new_target);
1267  }
1268  else // check wether link target is same installation
1269  {
1270  if (ilInternalLink::_extractInstOfTarget($target) == IL_INST_ID &&
1271  IL_INST_ID > 0 && $type != "RepositoryItem")
1272  {
1273  $new_target = ilInternalLink::_removeInstFromTarget($target);
1274  if (ilInternalLink::_exists($type, $new_target))
1275  {
1276  $res->nodeset[$i]->set_attribute("Target", $new_target);
1277  }
1278  }
1279  }
1280 
1281  }
1282  unset($xpc);
1283 
1284  // resolve internal links in map areas
1285  $xpc = xpath_new_context($this->dom);
1286  $path = "//MediaAlias";
1287  $res =& xpath_eval($xpc, $path);
1288 //echo "<br><b>page::resolve</b><br>";
1289 //echo "Content:".htmlentities($this->getXMLFromDOM()).":<br>";
1290  for($i = 0; $i < count($res->nodeset); $i++)
1291  {
1292  $orig_id = $res->nodeset[$i]->get_attribute("OriginId");
1293  $id_arr = explode("_", $orig_id);
1294  $mob_id = $id_arr[count($id_arr) - 1];
1296  }
1297  }
1298 
1305  function moveIntLinks($a_from_to)
1306  {
1307  $this->buildDom();
1308 
1309  // resolve normal internal links
1310  $xpc = xpath_new_context($this->dom);
1311  $path = "//IntLink";
1312  $res =& xpath_eval($xpc, $path);
1313  for($i = 0; $i < count($res->nodeset); $i++)
1314  {
1315  $target = $res->nodeset[$i]->get_attribute("Target");
1316  $type = $res->nodeset[$i]->get_attribute("Type");
1317  $obj_id = ilInternalLink::_extractObjIdOfTarget($target);
1318  if ($a_from_to[$obj_id] > 0 && is_int(strpos($target, "__")))
1319  {
1320  if ($type == "PageObject" && ilLMObject::_lookupType($a_from_to[$obj_id]) == "pg")
1321  {
1322  $res->nodeset[$i]->set_attribute("Target", "il__pg_".$a_from_to[$obj_id]);
1323  }
1324  if ($type == "StructureObject" && ilLMObject::_lookupType($a_from_to[$obj_id]) == "st")
1325  {
1326  $res->nodeset[$i]->set_attribute("Target", "il__st_".$a_from_to[$obj_id]);
1327  }
1328  }
1329  }
1330  unset($xpc);
1331 
1332  // map areas
1333  $this->addHierIDs();
1334  $xpc = xpath_new_context($this->dom);
1335  $path = "//MediaAlias";
1336  $res =& xpath_eval($xpc, $path);
1337 
1338  require_once("Services/MediaObjects/classes/class.ilMediaItem.php");
1339  require_once("Services/COPage/classes/class.ilMediaAliasItem.php");
1340 
1341  for($i = 0; $i < count($res->nodeset); $i++)
1342  {
1343  $media_object_node = $res->nodeset[$i]->parent_node();
1344  $page_content_node = $media_object_node->parent_node();
1345  $c_hier_id = $page_content_node->get_attribute("HierId");
1346 
1347  // first check, wheter we got instance map areas -> take these
1348  $std_alias_item = new ilMediaAliasItem($this->dom,
1349  $c_hier_id, "Standard");
1350  $areas = $std_alias_item->getMapAreas();
1351  $correction_needed = false;
1352  if (count($areas) > 0)
1353  {
1354  // check if correction needed
1355  foreach($areas as $area)
1356  {
1357  if ($area["Type"] == "PageObject" ||
1358  $area["Type"] == "StructureObject")
1359  {
1360  $t = $area["Target"];
1361  $tid = _extractObjIdOfTarget($t);
1362  if ($a_from_to[$tid] > 0)
1363  {
1364  $correction_needed = true;
1365  }
1366  }
1367  }
1368  }
1369  else
1370  {
1371  $areas = array();
1372 
1373  // get object map areas and check whether at least one must
1374  // be corrected
1375  $oid = $res->nodeset[$i]->get_attribute("OriginId");
1376  if (substr($oid, 0, 4) =="il__")
1377  {
1378  $id_arr = explode("_", $oid);
1379  $id = $id_arr[count($id_arr) - 1];
1380 
1381  $mob = new ilObjMediaObject($id);
1382  $med_item = $mob->getMediaItem("Standard");
1383  $med_areas = $med_item->getMapAreas();
1384 
1385  foreach($med_areas as $area)
1386  {
1387  $link_type = ($area->getLinkType() == "int")
1388  ? "IntLink"
1389  : "ExtLink";
1390 
1391  $areas[] = array(
1392  "Nr" => $area->getNr(),
1393  "Shape" => $area->getShape(),
1394  "Coords" => $area->getCoords(),
1395  "Link" => array(
1396  "LinkType" => $link_type,
1397  "Href" => $area->getHref(),
1398  "Title" => $area->getTitle(),
1399  "Target" => $area->getTarget(),
1400  "Type" => $area->getType(),
1401  "TargetFrame" => $area->getTargetFrame()
1402  )
1403  );
1404 
1405  if ($area->getType() == "PageObject" ||
1406  $area->getType() == "StructureObject")
1407  {
1408  $t = $area->getTarget();
1410  if ($a_from_to[$tid] > 0)
1411  {
1412  $correction_needed = true;
1413  }
1414 //var_dump($a_from_to);
1415  }
1416  }
1417  }
1418  }
1419 
1420  // correct map area links
1421  if ($correction_needed)
1422  {
1423  $std_alias_item->deleteAllMapAreas();
1424  foreach($areas as $area)
1425  {
1426  if ($area["Link"]["LinkType"] == "IntLink")
1427  {
1428  $target = $area["Link"]["Target"];
1429  $type = $area["Link"]["Type"];
1430  $obj_id = ilInternalLink::_extractObjIdOfTarget($target);
1431  if ($a_from_to[$obj_id] > 0)
1432  {
1433  if ($type == "PageObject" && ilLMObject::_lookupType($a_from_to[$obj_id]) == "pg")
1434  {
1435  $area["Link"]["Target"] = "il__pg_".$a_from_to[$obj_id];
1436  }
1437  if ($type == "StructureObject" && ilLMObject::_lookupType($a_from_to[$obj_id]) == "st")
1438  {
1439  $area["Link"]["Target"] = "il__st_".$a_from_to[$obj_id];
1440  }
1441  }
1442  }
1443 
1444  $std_alias_item->addMapArea($area["Shape"], $area["Coords"],
1445  $area["Link"]["Title"],
1446  array( "Type" => $area["Link"]["Type"],
1447  "TargetFrame" => $area["Link"]["TargetFrame"],
1448  "Target" => $area["Link"]["Target"],
1449  "Href" => $area["Link"]["Href"],
1450  "LinkType" => $area["Link"]["LinkType"],
1451  ));
1452  }
1453  }
1454  }
1455  unset($xpc);
1456 
1457  }
1458 
1464  static function _handleImportRepositoryLinks($a_rep_import_id, $a_rep_type, $a_rep_ref_id)
1465  {
1466  include_once("./Services/COPage/classes/class.ilInternalLink.php");
1467 
1468 //echo "-".$a_rep_import_id."-".$a_rep_ref_id."-";
1469  $sources = ilInternalLink::_getSourcesOfTarget("obj",
1470  ilInternalLink::_extractObjIdOfTarget($a_rep_import_id),
1471  ilInternalLink::_extractInstOfTarget($a_rep_import_id));
1472 //var_dump($sources);
1473  foreach($sources as $source)
1474  {
1475 //echo "A";
1476  if ($source["type"] == "lm:pg")
1477  {
1478 //echo "B";
1479  $page_obj = new ilPageObject("lm", $source["id"], false);
1480  if (!$page_obj->page_not_found)
1481  {
1482 //echo "C";
1483  $page_obj->handleImportRepositoryLink($a_rep_import_id,
1484  $a_rep_type, $a_rep_ref_id);
1485  }
1486  $page_obj->update();
1487  }
1488  }
1489  }
1490 
1491  function handleImportRepositoryLink($a_rep_import_id, $a_rep_type, $a_rep_ref_id)
1492  {
1493  $this->buildDom();
1494 
1495  // resolve normal internal links
1496  $xpc = xpath_new_context($this->dom);
1497  $path = "//IntLink";
1498  $res =& xpath_eval($xpc, $path);
1499 //echo "1";
1500  for($i = 0; $i < count($res->nodeset); $i++)
1501  {
1502 //echo "2";
1503  $target = $res->nodeset[$i]->get_attribute("Target");
1504  $type = $res->nodeset[$i]->get_attribute("Type");
1505  if ($target == $a_rep_import_id && $type == "RepositoryItem")
1506  {
1507 //echo "setting:"."il__".$a_rep_type."_".$a_rep_ref_id;
1508  $res->nodeset[$i]->set_attribute("Target",
1509  "il__".$a_rep_type."_".$a_rep_ref_id);
1510  }
1511  }
1512  unset($xpc);
1513  }
1514 
1518  function createFromXML()
1519  {
1520  global $lng, $ilDB, $ilUser;
1521 
1522 //echo "<br>PageObject::createFromXML[".$this->getId()."]";
1523 
1524  if($this->getXMLContent() == "")
1525  {
1526  $this->setXMLContent("<PageObject></PageObject>");
1527  }
1528  // create object
1529  $query = "INSERT INTO page_object (page_id, parent_id, content, parent_type, create_user, last_change_user, created, last_change) VALUES ".
1530  "(".$ilDB->quote($this->getId()).",".
1531  $ilDB->quote($this->getParentId()).",".
1532  $ilDB->quote($this->getXMLContent()).
1533  ", ".$ilDB->quote($this->getParentType()).
1534  ", ".$ilDB->quote($ilUser->getId()).
1535  ", ".$ilDB->quote($ilUser->getId()).
1536  ", now(), now())";
1537 
1538  if(!$this->ilias->db->checkQuerySize($query))
1539  {
1540  $this->ilias->raiseError($lng->txt("check_max_allowed_packet_size"),$this->ilias->error_obj->MESSAGE);
1541  return false;
1542  }
1543 
1544  $this->ilias->db->query($query);
1545 //echo "created page:".htmlentities($this->getXMLContent())."<br>";
1546  }
1547 
1548  /*
1549  function &copy()
1550  {
1551  $page_object =& new ilPageObject($this->getParentType());
1552  $page_object->setParentId($this->getParentId());
1553  $page_object->setXMLXContent($this->getXMLContent());
1554  }*/
1555 
1556 
1560  function updateFromXML()
1561  {
1562  global $lng, $ilDB, $ilUser;
1563 
1564 //echo "<br>PageObject::updateFromXML[".$this->getId()."]";
1565 //echo "update:".ilUtil::prepareDBString(($this->getXMLContent())).":<br>";
1566 //echo "update:".htmlentities(ilUtil::prepareDBString(($this->getXMLContent()))).":<br>";
1567 
1568  $query = "UPDATE page_object ".
1569  "SET content = ".$ilDB->quote($this->getXMLContent())." ".
1570  ", parent_id = ".$ilDB->quote($this->getParentId())." ".
1571  ", last_change_user = ".$ilDB->quote($ilUser->getId())." ".
1572  ", last_change = now() ".
1573  "WHERE page_id = ".$ilDB->quote($this->getId())." AND parent_type=".
1574  $ilDB->quote($this->getParentType());
1575 
1576  if(!$this->ilias->db->checkQuerySize($query))
1577  {
1578  $this->ilias->raiseError($lng->txt("check_max_allowed_packet_size"),$this->ilias->error_obj->MESSAGE);
1579  return false;
1580  }
1581  $this->ilias->db->query($query);
1582 
1583  return true;
1584  }
1585 
1589  function update($a_validate = true, $a_no_history = false)
1590  {
1591  global $lng, $ilDB, $ilUser, $ilLog, $ilCtrl;
1592 //echo "<br>PageObject::update[".$this->getId()."],validate($a_validate)";
1593 //echo "\n<br>dump_all2:".$this->dom->dump_mem(0, "UTF-8").":";
1594 //echo "\n<br>PageObject::update:".$this->getXMLFromDom().":";
1595 //echo "<br>PageObject::update:".htmlentities($this->getXMLFromDom());
1596  // add missing pc ids
1597  if (!$this->checkPCIds())
1598  {
1599  $this->insertPCIds();
1600  }
1601 
1602  // test validating
1603  if($a_validate)
1604  {
1605  $errors = $this->validateDom();
1606  }
1607 
1608 //echo "-".htmlentities($this->getXMLFromDom())."-"; exit;
1609  if(empty($errors))
1610  {
1611  $content = $this->getXMLFromDom();
1612 
1613  // this needs to be locked
1614 
1615  // write history entry
1616  $old_set = $ilDB->query("SELECT * FROM page_object WHERE ".
1617  "page_id = ".$ilDB->quote($this->getId())." AND ".
1618  "parent_type = ".$ilDB->quote($this->getParentType()));
1619  $last_nr_set = $ilDB->query("SELECT max(nr) as mnr FROM page_history WHERE ".
1620  "page_id = ".$ilDB->quote($this->getId())." AND ".
1621  "parent_type = ".$ilDB->quote($this->getParentType()));
1622  $last_nr = $last_nr_set->fetchRow(DB_FETCHMODE_ASSOC);
1623  if ($old_rec = $old_set->fetchRow(DB_FETCHMODE_ASSOC))
1624  {
1625  // only save, if something has changed
1626  if (($content != $old_rec["content"]) && !$a_no_history &&
1628  {
1629  if ($old_rec["content"] != "<PageObject></PageObject>")
1630  {
1631  $h_query = "REPLACE INTO page_history ".
1632  "(page_id, parent_type, hdate, parent_id, content, user, ilias_version, nr) VALUES (".
1633  $ilDB->quote($old_rec["page_id"]).",".
1634  $ilDB->quote($old_rec["parent_type"]).",".
1635  $ilDB->quote($old_rec["last_change"]).",".
1636  $ilDB->quote($old_rec["parent_id"]).",".
1637  $ilDB->quote($old_rec["content"]).",".
1638  $ilDB->quote($old_rec["last_change_user"]).",".
1639  $ilDB->quote(ILIAS_VERSION_NUMERIC).",".
1640  $ilDB->quote($last_nr["mnr"] + 1).")";
1641 //echo "<br><br>+$a_no_history+$h_query";
1642  $ilDB->query($h_query);
1643  $this->saveMobUsage($old_rec["content"], $last_nr["mnr"] + 1);
1644  $this->saveFileUsage($old_rec["content"], $last_nr["mnr"] + 1);
1645  $this->history_saved = true; // only save one time
1646  }
1647  else
1648  {
1649  $this->history_saved = true; // do not save on first change
1650  }
1651  }
1652  }
1653 
1654  $query = "UPDATE page_object ".
1655  "SET content = ".$ilDB->quote($content)." ".
1656  ", parent_id= ".$ilDB->quote($this->getParentId())." ".
1657  ", last_change_user= ".$ilDB->quote($ilUser->getId())." ".
1658  ", last_change = now() ".
1659  " WHERE page_id = ".$ilDB->quote($this->getId()).
1660  " AND parent_type= ".$ilDB->quote($this->getParentType());
1661  if(!$this->ilias->db->checkQuerySize($query))
1662  {
1663  $this->ilias->raiseError($lng->txt("check_max_allowed_packet_size"),$this->ilias->error_obj->MESSAGE);
1664  return false;
1665  }
1666 
1667  $this->ilias->db->query($query);
1668 
1669  // handle media object usage
1670  include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
1672  $this->getParentType().":pg", $this->getId());
1673  $this->saveMobUsage($this->getXMLFromDom());
1674  foreach($mob_ids as $mob) // check, whether media object can be deleted
1675  {
1676  if (ilObject::_exists($mob) && ilObject::_lookupType($mob) == "mob")
1677  {
1678  $mob_obj = new ilObjMediaObject($mob);
1679  $usages = $mob_obj->getUsages();
1680  if (count($usages) == 0) // delete, if no usage exists
1681  {
1682  $mob_obj->delete();
1683  }
1684  }
1685  }
1686 
1687  // handle file usages
1688  include_once("./Modules/File/classes/class.ilObjFile.php");
1689  $file_ids = ilObjFile::_getFilesOfObject(
1690  $this->getParentType().":pg", $this->getId());
1691  $this->saveFileUsage();
1692  foreach($file_ids as $file) // check, whether file object can be deleted
1693  {
1694  if (ilObject::_exists($file))
1695  {
1696  $file_obj = new ilObjFile($file, false);
1697  $usages = $file_obj->getUsages();
1698  if (count($usages) == 0) // delete, if no usage exists
1699  {
1700  $file_obj->delete();
1701  }
1702  }
1703  }
1704 
1705  // save internal link information
1706  $this->saveInternalLinks($this->getXMLFromDom());
1707  $this->callUpdateListeners();
1708 //echo "<br>PageObject::update:".htmlentities($this->getXMLContent()).":";
1709  return true;
1710  }
1711  else
1712  {
1713  return $errors;
1714  }
1715  }
1716 
1717 
1721  function delete()
1722  {
1723  global $ilDB;
1724 
1725  $mobs = array();
1726  $files = array();
1727 
1728  if (!$this->page_not_found)
1729  {
1730  $this->buildDom();
1731  $mobs = $this->collectMediaObjects(false);
1732  $files = $this->collectFileItems();
1733  }
1734 
1735  // delete mob usages
1736  $this->saveMobUsage("<dummy></dummy>");
1737 
1738  // delete internal links
1739  $this->saveInternalLinks("<dummy></dummy>");
1740 
1741  // delete all file usages
1742  include_once("./Modules/File/classes/class.ilObjFile.php");
1743  ilObjFile::_deleteAllUsages($this->getParentType().":pg", $this->getId());
1744 
1745  // delete page_object entry
1746  $query = "DELETE FROM page_object ".
1747  "WHERE page_id = ".$ilDB->quote($this->getId()).
1748  " AND parent_type= ".$ilDB->quote($this->getParentType());
1749  $this->ilias->db->query($query);
1750 
1751  // delete media objects
1752  foreach ($mobs as $mob_id)
1753  {
1754  if(ilObject::_lookupType($mob_id) != 'mob')
1755  {
1756  $GLOBALS['ilLog']->write(__METHOD__.': Type mismatch. Ignoring mob with id: '.$mob_id);
1757  continue;
1758  }
1759 
1760  if (ilObject::_exists($mob_id))
1761  {
1762  $mob_obj =& new ilObjMediaObject($mob_id);
1763  $mob_obj->delete();
1764  }
1765  }
1766 
1767  include_once("./Modules/File/classes/class.ilObjFile.php");
1768  foreach ($files as $file_id)
1769  {
1770  if (ilObject::_exists($file_id))
1771  {
1772  $file_obj =& new ilObjFile($file_id, false);
1773  $file_obj->delete();
1774  }
1775  }
1776 
1777  }
1778 
1779 
1785  function saveMobUsage($a_xml, $a_old_nr = 0)
1786  {
1787  $doc = domxml_open_mem($a_xml);
1788 
1789  // media aliases
1790  $xpc = xpath_new_context($doc);
1791  $path = "//MediaAlias";
1792  $res =& xpath_eval($xpc, $path);
1793  $usages = array();
1794  for ($i=0; $i < count($res->nodeset); $i++)
1795  {
1796  $id_arr = explode("_", $res->nodeset[$i]->get_attribute("OriginId"));
1797  $mob_id = $id_arr[count($id_arr) - 1];
1798  if ($mob_id > 0)
1799  {
1800  $usages[$mob_id] = true;
1801  }
1802  }
1803 
1804  // media objects
1805  $xpc = xpath_new_context($doc);
1806  $path = "//MediaObject/MetaData/General/Identifier";
1807  $res =& xpath_eval($xpc, $path);
1808  for ($i=0; $i < count($res->nodeset); $i++)
1809  {
1810  $mob_entry = $res->nodeset[$i]->get_attribute("Entry");
1811  $mob_arr = explode("_", $mob_entry);
1812  $mob_id = $mob_arr[count($mob_arr) - 1];
1813  if ($mob_id > 0)
1814  {
1815  $usages[$mob_id] = true;
1816  }
1817  }
1818 
1819  // internal links
1820  $xpc = xpath_new_context($doc);
1821  $path = "//IntLink[@Type='MediaObject']";
1822  $res =& xpath_eval($xpc, $path);
1823  for ($i=0; $i < count($res->nodeset); $i++)
1824  {
1825  $mob_target = $res->nodeset[$i]->get_attribute("Target");
1826  $mob_arr = explode("_", $mob_target);
1827  $mob_id = $mob_arr[count($mob_arr) - 1];
1828  if ($mob_id > 0)
1829  {
1830  $usages[$mob_id] = true;
1831  }
1832  }
1833 
1834  include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
1835  ilObjMediaObject::_deleteAllUsages($this->getParentType().":pg", $this->getId(), $a_old_nr);
1836  foreach($usages as $mob_id => $val)
1837  {
1838  ilObjMediaObject::_saveUsage($mob_id, $this->getParentType().":pg", $this->getId(), $a_old_nr);
1839  }
1840  }
1841 
1845  function saveFileUsage($a_xml = "", $a_old_nr = 0)
1846  {
1847  $file_ids = $this->collectFileItems($a_xml, $a_old_nr);
1848  include_once("./Modules/File/classes/class.ilObjFile.php");
1849  ilObjFile::_deleteAllUsages($this->getParentType().":pg", $this->getId(), $a_old_nr);
1850  foreach($file_ids as $file_id)
1851  {
1852  ilObjFile::_saveUsage($file_id, $this->getParentType().":pg", $this->getId(), $a_old_nr);
1853  }
1854  }
1855 
1861  {
1862  include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
1863  include_once("./Modules/File/classes/class.ilObjFile.php");
1865  $this->getId());
1867  $this->getId());
1868  $objs = array_merge($mobs, $files);
1869  return ilObject::_getLastUpdateOfObjects($objs);
1870  }
1871 
1877  function saveInternalLinks($a_xml)
1878  {
1879 //echo "<br>PageObject::saveInternalLinks[".$this->getId()."]";
1880  $doc = domxml_open_mem($a_xml);
1881 
1882 
1883  include_once("./Services/COPage/classes/class.ilInternalLink.php");
1885 
1886  // get all internal links
1887  $xpc = xpath_new_context($doc);
1888  $path = "//IntLink";
1889  $res =& xpath_eval($xpc, $path);
1890  for ($i=0; $i < count($res->nodeset); $i++)
1891  {
1892  $link_type = $res->nodeset[$i]->get_attribute("Type");
1893 
1894  switch ($link_type)
1895  {
1896  case "StructureObject":
1897  $t_type = "st";
1898  break;
1899 
1900  case "PageObject":
1901  $t_type = "pg";
1902  break;
1903 
1904  case "GlossaryItem":
1905  $t_type = "git";
1906  break;
1907 
1908  case "MediaObject":
1909  $t_type = "mob";
1910  break;
1911 
1912  case "RepositoryItem":
1913  $t_type = "obj";
1914  break;
1915  }
1916 
1917  $target = $res->nodeset[$i]->get_attribute("Target");
1918  $target_arr = explode("_", $target);
1919  $t_id = $target_arr[count($target_arr) - 1];
1920 
1921  // link to other internal object
1922  if (is_int(strpos($target, "__")))
1923  {
1924  $t_inst = 0;
1925  }
1926  else // link to unresolved object in other installation
1927  {
1928  $t_inst = $target_arr[1];
1929  }
1930 
1931  if ($t_id > 0)
1932  {
1933  ilInternalLink::_saveLink($this->getParentType().":pg", $this->getId(), $t_type,
1934  $t_id, $t_inst);
1935  }
1936  }
1937 
1938  }
1939 
1940 
1944  function create()
1945  {
1946  $this->createFromXML();
1947  }
1948 
1956  function deleteContent($a_hid, $a_update = true, $a_pcid = "")
1957  {
1958  $curr_node =& $this->getContentNode($a_hid, $a_pcid);
1959  $curr_node->unlink_node($curr_node);
1960  if ($a_update)
1961  {
1962  return $this->update();
1963  }
1964  }
1965 
1973  function deleteContents($a_hids, $a_update = true)
1974  {
1975  if (!is_array($a_hids))
1976  {
1977  return;
1978  }
1979  foreach($a_hids as $a_hid)
1980  {
1981  $a_hid = explode(":", $a_hid);
1982 //echo "-".$a_hid[0]."-".$a_hid[1]."-";
1983  $curr_node =& $this->getContentNode($a_hid[0], $a_hid[1]);
1984  if (is_object($curr_node))
1985  {
1986  $parent_node = $curr_node->parent_node();
1987  if ($parent_node->node_name() != "TableRow")
1988  {
1989  $curr_node->unlink_node($curr_node);
1990  }
1991  }
1992  }
1993  if ($a_update)
1994  {
1995  return $this->update();
1996  }
1997  }
1998 
2003  function switchEnableMultiple($a_hids, $a_update = true)
2004  {
2005  if (!is_array($a_hids))
2006  {
2007  return;
2008  }
2009  $obj = & $this->content_obj;
2010 
2011  foreach($a_hids as $a_hid)
2012  {
2013  $a_hid = explode(":", $a_hid);
2014 //echo "-".$a_hid[0]."-".$a_hid[1]."-";
2015  $curr_node =& $this->getContentNode($a_hid[0], $a_hid[1]);
2016  if (is_object($curr_node))
2017  {
2018  if ($curr_node->node_name() == "PageContent")
2019  {
2020  $cont_obj =& $this->getContentObject($a_hid[0], $a_hid[1]);
2021  if ($cont_obj->isEnabled ())
2022  $cont_obj->disable ();
2023  else
2024  $cont_obj->enable ();
2025  }
2026  }
2027  }
2028 
2029  if ($a_update)
2030  {
2031  return $this->update();
2032  }
2033  }
2034 
2035 
2043  function deleteContentFromHierId($a_hid, $a_update = true)
2044  {
2045  $hier_ids = $this->getHierIds();
2046 
2047  // iterate all hierarchical ids
2048  foreach ($hier_ids as $hier_id)
2049  {
2050  // delete top level nodes only
2051  if (!is_int(strpos($hier_id, "_")))
2052  {
2053  if ($hier_id != "pg" && $hier_id >= $a_hid)
2054  {
2055  $curr_node =& $this->getContentNode($hier_id);
2056  $curr_node->unlink_node($curr_node);
2057  }
2058  }
2059  }
2060  if ($a_update)
2061  {
2062  return $this->update();
2063  }
2064  }
2065 
2073  function deleteContentBeforeHierId($a_hid, $a_update = true)
2074  {
2075  $hier_ids = $this->getHierIds();
2076 
2077  // iterate all hierarchical ids
2078  foreach ($hier_ids as $hier_id)
2079  {
2080  // delete top level nodes only
2081  if (!is_int(strpos($hier_id, "_")))
2082  {
2083  if ($hier_id != "pg" && $hier_id < $a_hid)
2084  {
2085  $curr_node =& $this->getContentNode($hier_id);
2086  $curr_node->unlink_node($curr_node);
2087  }
2088  }
2089  }
2090  if ($a_update)
2091  {
2092  return $this->update();
2093  }
2094  }
2095 
2096 
2104  function _moveContentAfterHierId(&$a_source_page, &$a_target_page, $a_hid)
2105  {
2106  $hier_ids = $a_source_page->getHierIds();
2107 
2108  $copy_ids = array();
2109 
2110  // iterate all hierarchical ids
2111  foreach ($hier_ids as $hier_id)
2112  {
2113  // move top level nodes only
2114  if (!is_int(strpos($hier_id, "_")))
2115  {
2116  if ($hier_id != "pg" && $hier_id >= $a_hid)
2117  {
2118  $copy_ids[] = $hier_id;
2119  }
2120  }
2121  }
2122  asort($copy_ids);
2123 
2124  $parent_node =& $a_target_page->getContentNode("pg");
2125  $target_dom =& $a_target_page->getDom();
2126  $parent_childs =& $parent_node->child_nodes();
2127  $cnt_parent_childs = count($parent_childs);
2128 //echo "-$cnt_parent_childs-";
2129  $first_child =& $parent_childs[0];
2130  foreach($copy_ids as $copy_id)
2131  {
2132  $source_node =& $a_source_page->getContentNode($copy_id);
2133 
2134  $new_node =& $source_node->clone_node(true);
2135  $new_node->unlink_node($new_node);
2136 
2137  $source_node->unlink_node($source_node);
2138 
2139  if($cnt_parent_childs == 0)
2140  {
2141  $new_node =& $parent_node->append_child($new_node);
2142  }
2143  else
2144  {
2145  //$target_dom->import_node($new_node);
2146  $new_node =& $first_child->insert_before($new_node, $first_child);
2147  }
2148  $parent_childs =& $parent_node->child_nodes();
2149 
2150  //$cnt_parent_childs++;
2151  }
2152 
2153  $a_target_page->update();
2154  $a_source_page->update();
2155 
2156  }
2157 
2161  function insertContent(&$a_cont_obj, $a_pos, $a_mode = IL_INSERT_AFTER, $a_pcid = "")
2162  {
2163  // move mode into container elements is always INSERT_CHILD
2164  $curr_node = $this->getContentNode($a_pos, $a_pcid);
2165  $curr_name = $curr_node->node_name();
2166  if (($curr_name == "TableData") || ($curr_name == "PageObject") ||
2167  ($curr_name == "ListItem") || ($curr_name == "Section")
2168  || ($curr_name == "Tab"))
2169  {
2170  $a_mode = IL_INSERT_CHILD;
2171  }
2172 
2173  $hid = $curr_node->get_attribute("HierId");
2174  if ($hid != "")
2175  {
2176 //echo "-".$a_pos."-".$hid."-";
2177  $a_pos = $hid;
2178  }
2179 
2180  if($a_mode != IL_INSERT_CHILD) // determine parent hierarchical id
2181  { // of sibling at $a_pos
2182  $pos = explode("_", $a_pos);
2183  $target_pos = array_pop($pos);
2184  $parent_pos = implode($pos, "_");
2185  }
2186  else // if we should insert a child, $a_pos is alreade the hierarchical id
2187  { // of the parent node
2188  $parent_pos = $a_pos;
2189  }
2190 
2191  // get the parent node
2192  if($parent_pos != "")
2193  {
2194  $parent_node =& $this->getContentNode($parent_pos);
2195  }
2196  else
2197  {
2198  $parent_node =& $this->getNode();
2199  }
2200 
2201  // count the parent children
2202  $parent_childs =& $parent_node->child_nodes();
2203  $cnt_parent_childs = count($parent_childs);
2204 //echo "ZZ$a_mode";
2205  switch ($a_mode)
2206  {
2207  // insert new node after sibling at $a_pos
2208  case IL_INSERT_AFTER:
2209  $new_node =& $a_cont_obj->getNode();
2210  //$a_pos = ilPageContent::incEdId($a_pos);
2211  //$curr_node =& $this->getContentNode($a_pos);
2212 //echo "behind $a_pos:";
2213  if($succ_node =& $curr_node->next_sibling())
2214  {
2215  $new_node =& $succ_node->insert_before($new_node, $succ_node);
2216  }
2217  else
2218  {
2219 //echo "movin doin append_child";
2220  $new_node =& $parent_node->append_child($new_node);
2221  }
2222  $a_cont_obj->setNode($new_node);
2223  break;
2224 
2225  case IL_INSERT_BEFORE:
2226 //echo "INSERT_BEF";
2227  $new_node =& $a_cont_obj->getNode();
2228  $succ_node =& $this->getContentNode($a_pos);
2229  $new_node =& $succ_node->insert_before($new_node, $succ_node);
2230  $a_cont_obj->setNode($new_node);
2231  break;
2232 
2233  // insert new node as first child of parent $a_pos (= $a_parent)
2234  case IL_INSERT_CHILD:
2235 //echo "insert as child:parent_childs:$cnt_parent_childs:<br>";
2236  $new_node =& $a_cont_obj->getNode();
2237  if($cnt_parent_childs == 0)
2238  {
2239  $new_node =& $parent_node->append_child($new_node);
2240  }
2241  else
2242  {
2243  $new_node =& $parent_childs[0]->insert_before($new_node, $parent_childs[0]);
2244  }
2245  $a_cont_obj->setNode($new_node);
2246 //echo "PP";
2247  break;
2248  }
2249 
2250  }
2251 
2252 
2257  function moveContentBefore($a_source, $a_target, $a_spcid = "", $a_tpcid = "")
2258  {
2259  if($a_source == $a_target)
2260  {
2261  return;
2262  }
2263 
2264  // clone the node
2265  $content =& $this->getContentObject($a_source, $a_spcid);
2266  $source_node =& $content->getNode();
2267  $clone_node =& $source_node->clone_node(true);
2268 
2269  // delete source node
2270  $this->deleteContent($a_source, false, $a_spcid);
2271 
2272  // insert cloned node at target
2273  $content->setNode($clone_node);
2274  $this->insertContent($content, $a_target, IL_INSERT_BEFORE, $a_tpcid);
2275  return $this->update();
2276 
2277  }
2278 
2283  function moveContentAfter($a_source, $a_target, $a_spcid = "", $a_tpcid = "")
2284  {
2285  if($a_source == $a_target)
2286  {
2287  return;
2288  }
2289 
2290  // clone the node
2291  $content =& $this->getContentObject($a_source, $a_spcid);
2292  $source_node =& $content->getNode();
2293  $clone_node =& $source_node->clone_node(true);
2294 
2295  // delete source node
2296  $this->deleteContent($a_source, false, $a_spcid);
2297 
2298  // insert cloned node at target
2299  $content->setNode($clone_node);
2300  $this->insertContent($content, $a_target, IL_INSERT_AFTER, $a_tpcid);
2301  return $this->update();
2302  }
2303 
2307  function bbCode2XML(&$a_content)
2308  {
2309  $a_content = eregi_replace("\[com\]","<Comment>",$a_content);
2310  $a_content = eregi_replace("\[\/com\]","</Comment>",$a_content);
2311  $a_content = eregi_replace("\[emp]","<Emph>",$a_content);
2312  $a_content = eregi_replace("\[\/emp\]","</Emph>",$a_content);
2313  $a_content = eregi_replace("\[str]","<Strong>",$a_content);
2314  $a_content = eregi_replace("\[\/str\]","</Strong>",$a_content);
2315  }
2316 
2321  function insertInstIntoIDs($a_inst, $a_res_ref_to_obj_id = true)
2322  {
2323  // insert inst id into internal links
2324  $xpc = xpath_new_context($this->dom);
2325  $path = "//IntLink";
2326  $res =& xpath_eval($xpc, $path);
2327  for($i = 0; $i < count($res->nodeset); $i++)
2328  {
2329  $target = $res->nodeset[$i]->get_attribute("Target");
2330  $type = $res->nodeset[$i]->get_attribute("Type");
2331 
2332  if (substr($target, 0, 4) == "il__")
2333  {
2334  $id = substr($target, 4, strlen($target) - 4);
2335 
2336  // convert repository links obj_<ref_id> to <type>_<obj_id>
2337  if ($a_res_ref_to_obj_id && $type == "RepositoryItem")
2338  {
2339  $id_arr = explode("_", $id);
2340  $obj_id = ilObject::_lookupObjId($id_arr[1]);
2341  $otype = ilObject::_lookupType($obj_id);
2342  if ($obj_id > 0)
2343  {
2344  $id = $otype."_".$obj_id;
2345  }
2346  }
2347  $new_target = "il_".$a_inst."_".$id;
2348  $res->nodeset[$i]->set_attribute("Target", $new_target);
2349  }
2350  }
2351  unset($xpc);
2352 
2353  // insert inst id into media aliases
2354  $xpc = xpath_new_context($this->dom);
2355  $path = "//MediaAlias";
2356  $res =& xpath_eval($xpc, $path);
2357  for($i = 0; $i < count($res->nodeset); $i++)
2358  {
2359  $origin_id = $res->nodeset[$i]->get_attribute("OriginId");
2360  if (substr($origin_id, 0, 4) == "il__")
2361  {
2362  $new_id = "il_".$a_inst."_".substr($origin_id, 4, strlen($origin_id) - 4);
2363  $res->nodeset[$i]->set_attribute("OriginId", $new_id);
2364  }
2365  }
2366  unset($xpc);
2367 
2368  // insert inst id file item identifier entries
2369  $xpc = xpath_new_context($this->dom);
2370  $path = "//FileItem/Identifier";
2371  $res =& xpath_eval($xpc, $path);
2372  for($i = 0; $i < count($res->nodeset); $i++)
2373  {
2374  $origin_id = $res->nodeset[$i]->get_attribute("Entry");
2375  if (substr($origin_id, 0, 4) == "il__")
2376  {
2377  $new_id = "il_".$a_inst."_".substr($origin_id, 4, strlen($origin_id) - 4);
2378  $res->nodeset[$i]->set_attribute("Entry", $new_id);
2379  }
2380  }
2381  unset($xpc);
2382 
2383  // insert inst id into
2384  $xpc = xpath_new_context($this->dom);
2385  $path = "//Question";
2386  $res =& xpath_eval($xpc, $path);
2387  for($i = 0; $i < count($res->nodeset); $i++)
2388  {
2389  $qref = $res->nodeset[$i]->get_attribute("QRef");
2390 //echo "<br>setted:".$qref;
2391  if (substr($qref, 0, 4) == "il__")
2392  {
2393  $new_id = "il_".$a_inst."_".substr($qref, 4, strlen($qref) - 4);
2394 //echo "<br>setting:".$new_id;
2395  $res->nodeset[$i]->set_attribute("QRef", $new_id);
2396  }
2397  }
2398  unset($xpc);
2399 
2400  }
2401 
2406  function highlightText($a_text, $proglang, $autoindent)
2407  {
2408 
2409  if (!$this->hasHighlighter($proglang)) {
2410  $proglang="plain";
2411  }
2412 
2413  require_once("./Services/COPage/syntax_highlight/php/HFile/HFile_".$proglang.".php");
2414  $classname = "HFile_$proglang";
2415  $h_instance = new $classname();
2416  if ($autoindent == "n") {
2417  $h_instance ->notrim = 1;
2418  $h_instance ->indent = array ("");
2419  $h_instance ->unindent = array ("");
2420  }
2421 
2422  $highlighter = new Core($h_instance, new Output_css());
2423  $a_text = $highlighter->highlight_text(html_entity_decode($a_text));
2424 
2425  return $a_text;
2426  }
2427 
2428  function hasHighlighter ($hfile_ext) {
2429  return file_exists ("Services/COPage/syntax_highlight/php/HFile/HFile_".$hfile_ext.".php");
2430  }
2431 
2437  function insertSourceCodeParagraphs($a_output, $outputmode = "presentation")
2438  {
2439  $xpc = xpath_new_context($this->dom);
2440  $path = "//Paragraph"; //"[@Characteristic = 'Code']";
2441  $res = & xpath_eval($xpc, $path);
2442  for($i = 0; $i < count($res->nodeset); $i++)
2443  {
2444  $context_node = $res->nodeset[$i];
2445  $char = $context_node->get_attribute('Characteristic');
2446 
2447  if ($char != "Code")
2448  continue;
2449 
2450  $n = $context_node->parent_node();
2451  $char = $context_node->get_attribute('Characteristic');
2452  $subchar = $context_node->get_attribute('SubCharacteristic');
2453  $showlinenumbers = $context_node->get_attribute('ShowLineNumbers');
2454  $downloadtitle = $context_node->get_attribute('DownloadTitle');
2455  $autoindent = $context_node->get_attribute('AutoIndent');
2456 
2457  $content = "";
2458 
2459  // get XML Content
2460  $childs = $context_node->child_nodes();
2461 
2462  for($j=0; $j<count($childs); $j++)
2463  {
2464  $content .= $this->dom->dump_node($childs[$j]);
2465  }
2466 
2467  while ($context_node->has_child_nodes ())
2468  {
2469  $node_del = $context_node->first_child ();
2470  $context_node->remove_child ($node_del);
2471  }
2472 
2473  $content = str_replace("<br />", "<br/>", utf8_decode($content) );
2474  $content = str_replace("<br/>", "\n", $content);
2475  $rownums = count(split ("\n",$content));
2476 
2477  $plain_content = html_entity_decode($content);
2478  $plain_content = preg_replace ("/\&#x([1-9a-f]{2});?/ise","chr (base_convert (\\1, 16, 10))",$plain_content);
2479  $plain_content = preg_replace ("/\&#(\d+);?/ise","chr (\\1)",$plain_content);
2480  $content = utf8_encode($this->highlightText($plain_content, $subchar, $autoindent));
2481 
2482  $content = str_replace("&amp;lt;", "&lt;", $content);
2483  $content = str_replace("&amp;gt;", "&gt;", $content);
2484 // $content = str_replace("&", "&amp;", $content);
2485 //var_dump($content);
2486  $rows = "<TR valign=\"top\">";
2487  $rownumbers = "";
2488  $linenumbers= "";
2489 
2490  //if we have to show line numbers
2491  if (strcmp($showlinenumbers,"y")==0)
2492  {
2493  $linenumbers = "<TD nowrap=\"nowrap\" class=\"ilc_LineNumbers\" >";
2494  $linenumbers .= "<PRE class=\"ilc_Code\">";
2495 
2496  for ($j=0; $j < $rownums; $j++)
2497  {
2498  $indentno = strlen($rownums) - strlen($j+1) + 2;
2499  $rownumeration = ($j+1);
2500  $linenumbers .= "<span class=\"ilc_LineNumber\">$rownumeration</span>";
2501  if ($j < $rownums-1)
2502  {
2503  $linenumbers .= "\n";
2504  }
2505  }
2506  $linenumbers .= "</PRE>";
2507  $linenumbers .= "</TD>";
2508  }
2509 
2510  $rows .= $linenumbers."<TD class=\"ilc_Sourcecode\"><PRE class=\"ilc_Code\">".$content."</PRE></TD>";
2511  $rows .= "</TR>";
2512 
2513  // fix for ie explorer which is not able to produce empty line feeds with <br /><br />;
2514  // workaround: add a space after each br.
2515  $newcontent = str_replace("\n", "<br/>",$rows);
2516  // fix for IE
2517  $newcontent = str_replace("<br/><br/>", "<br/> <br/>",$newcontent);
2518  // falls drei hintereinander...
2519  $newcontent = str_replace("<br/><br/>", "<br/> <br/>",$newcontent);
2520 
2521  //$context_node->set_content($newcontent);
2522 //var_dump($newcontent);
2523  $a_output = str_replace("[[[[[Code;".($i + 1)."]]]]]", $newcontent, $a_output);
2524 
2525  if ($outputmode != "presentation" && is_object($this->offline_handler)
2526  && trim($downloadtitle) != "")
2527  {
2528  // call code handler for offline versions
2529  $this->offline_handler->handleCodeParagraph ($this->id, $i + 1, $downloadtitle, $plain_content);
2530  }
2531  }
2532 
2533  return $a_output;
2534  }
2535 
2536 
2540  function checkPCIds()
2541  {
2542  $this->builddom();
2543  $mydom = $this->dom;
2544 
2545  $sep = $path = "";
2546  foreach ($this->id_elements as $el)
2547  {
2548  $path.= $sep."//".$el."[not(@PCID)]";
2549  $sep = " | ";
2550  }
2551 
2552  $xpc = xpath_new_context($mydom);
2553  $res = & xpath_eval($xpc, $path);
2554 
2555  if (count ($res->nodeset) > 0)
2556  {
2557  return false;
2558  }
2559  return true;
2560  }
2561 
2565  function insertPCIds()
2566  {
2567  $this->builddom();
2568  $mydom = $this->dom;
2569 
2570  $pcids = array();
2571 
2572  $sep = $path = "";
2573  foreach ($this->id_elements as $el)
2574  {
2575  $path.= $sep."//".$el."[@PCID]";
2576  $sep = " | ";
2577  }
2578 
2579  // get existing ids
2580  $xpc = xpath_new_context($mydom);
2581  $res = & xpath_eval($xpc, $path);
2582 
2583  for ($i = 0; $i < count ($res->nodeset); $i++)
2584  {
2585  $node = $res->nodeset[$i];
2586  $pcids[] = $node->get_attribute("PCID");
2587  }
2588 
2589  // add missing ones
2590  $sep = $path = "";
2591  foreach ($this->id_elements as $el)
2592  {
2593  $path.= $sep."//".$el."[not(@PCID)]";
2594  $sep = " | ";
2595  }
2596  $xpc = xpath_new_context($mydom);
2597  $res = & xpath_eval($xpc, $path);
2598 
2599  for ($i = 0; $i < count ($res->nodeset); $i++)
2600  {
2601  $node = $res->nodeset[$i];
2602  $id = ilUtil::randomHash(10, $pcids);
2603  $pcids[] = $id;
2604 //echo "setting-".$id."-";
2605  $res->nodeset[$i]->set_attribute("PCID", $id);
2606  }
2607  }
2608 
2613  {
2614  $this->builddom();
2615  $this->addHierIds();
2616  $mydom = $this->dom;
2617 
2618  // get existing ids
2619  $path = "//PageContent";
2620  $xpc = xpath_new_context($mydom);
2621  $res = & xpath_eval($xpc, $path);
2622 
2623  $hashes = array();
2624  for ($i = 0; $i < count ($res->nodeset); $i++)
2625  {
2626  $hier_id = $res->nodeset[$i]->get_attribute("HierId");
2627  $pc_id = $res->nodeset[$i]->get_attribute("PCID");
2628  $dump = $mydom->dump_node($res->nodeset[$i]);
2629  if (($hpos = strpos($dump, ' HierId="'.$hier_id.'"')) > 0)
2630  {
2631  $dump = substr($dump, 0, $hpos).
2632  substr($dump, $hpos + strlen(' HierId="'.$hier_id.'"'));
2633  }
2634 
2635  $childs = $res->nodeset[$i]->child_nodes();
2636  $content = "";
2637  if ($childs[0] && $childs[0]->node_name() == "Paragraph")
2638  {
2639  $content = $mydom->dump_node($childs[0]);
2640  $content = substr($content, strpos($content, ">") + 1,
2641  strrpos($content, "<") - (strpos($content, ">") + 1));
2642 //var_dump($content);
2643  $content = ilPCParagraph::xml2output($content);
2644 //var_dump($content);
2645  }
2646  //$hashes[$hier_id] =
2647  // array("PCID" => $pc_id, "hash" => md5($dump));
2648  $hashes[$pc_id] =
2649  array("hier_id" => $hier_id, "hash" => md5($dump), "content" => $content);
2650  }
2651 
2652  return $hashes;
2653  }
2654 
2655  function send_paragraph ($par_id, $filename)
2656  {
2657  $this->builddom();
2658 
2659  $mydom = $this->dom;
2660 
2661  $xpc = xpath_new_context($mydom);
2662 
2663  //$path = "//PageContent[position () = $par_id]/Paragraph";
2664  //$path = "//Paragraph[$par_id]";
2665  $path = "/descendant::Paragraph[position() = $par_id]";
2666 
2667  $res = & xpath_eval($xpc, $path);
2668 
2669  if (count ($res->nodeset) != 1)
2670  die ("Should not happen");
2671 
2672  $context_node = $res->nodeset[0];
2673 
2674  // get plain text
2675 
2676  $childs = $context_node->child_nodes();
2677 
2678  for($j=0; $j<count($childs); $j++)
2679  {
2680  $content .= $mydom->dump_node($childs[$j]);
2681  }
2682 
2683  $content = str_replace("<br />", "\n", $content);
2684  $content = str_replace("<br/>", "\n", $content);
2685 
2686  $plain_content = html_entity_decode($content);
2687 
2688  ilUtil::deliverData($plain_content, $filename);
2689  /*
2690  $file_type = "application/octet-stream";
2691  header("Content-type: ".$file_type);
2692  header("Content-disposition: attachment; filename=\"$filename\"");
2693  echo $plain_content;*/
2694  exit();
2695  }
2696 
2700  function getFO()
2701  {
2702  $xml = $this->getXMLFromDom(false, true, true);
2703  $xsl = file_get_contents("./Services/COPage/xsl/page_fo.xsl");
2704  $args = array( '/_xml' => $xml, '/_xsl' => $xsl );
2705  $xh = xslt_create();
2706 
2707  $params = array ();
2708 
2709 
2710  $fo = xslt_process($xh,"arg:/_xml","arg:/_xsl",NULL,$args, $params);
2711 
2712  // do some replacements
2713  $fo = str_replace("\n", "", $fo);
2714  $fo = str_replace("<br/>", "<br>", $fo);
2715  $fo = str_replace("<br>", "\n", $fo);
2716 
2717  xslt_free($xh);
2718 
2719  //
2720  $fo = substr($fo, strpos($fo,">") + 1);
2721 //echo "<br><b>fo:</b><br>".htmlentities($fo); flush();
2722  return $fo;
2723  }
2724 
2725  function registerOfflineHandler ($handler) {
2726  $this->offline_handler = $handler;
2727  }
2728 
2732  function _lookupContainsDeactivatedElements($a_id, $a_parent_type)
2733  {
2734  global $ilDB;
2735 
2736  $query = "SELECT * FROM page_object WHERE page_id = ".
2737  $ilDB->quote($a_id)." AND ".
2738  " parent_type = ".$ilDB->quote($a_parent_type)." AND ".
2739  " content LIKE '% Enabled=\"False\"%'";
2740  $obj_set = $ilDB->query($query);
2741 
2742  if ($obj_rec = $obj_set->fetchRow(DB_FETCHMODE_ASSOC))
2743  {
2744  return true;
2745  }
2746 
2747  return false;
2748  }
2749 
2754  {
2755  global $ilDB;
2756 
2757  $h_query = "SELECT * FROM page_history ".
2758  " WHERE page_id = ".$ilDB->quote($this->getId()).
2759  " AND parent_type = ".$ilDB->quote($this->getParentType()).
2760  " ORDER BY hdate DESC";
2761 
2762  $hset = $ilDB->query($h_query);
2763  $hentries = array();
2764 
2765  while ($hrec = $hset->fetchRow(DB_FETCHMODE_ASSOC))
2766  {
2767  $hrec["sortkey"] = $hrec["nr"];
2768  $hentries[] = $hrec;
2769  }
2770 
2771  return $hentries;
2772  }
2773 
2777  function getHistoryEntry($a_old_nr)
2778  {
2779  global $ilDB;
2780 
2781  $st = $ilDB->prepare("SELECT * FROM page_history ".
2782  " WHERE page_id = ? ".
2783  " AND parent_type = ? ".
2784  " AND nr = ?", array("integer", "text", "integer"));
2785  $res = $ilDB->execute($st,
2786  array($this->getId(), $this->getParentType(), $a_old_nr));
2787  if ($hrec = $ilDB->fetchAssoc($res))
2788  {
2789  return $hrec;
2790  }
2791 
2792  return false;
2793  }
2794 
2795 
2802  function getHistoryInfo($a_nr)
2803  {
2804  global $ilDB;
2805 
2806  // determine previous entry
2807  $st = $ilDB->prepare("SELECT MAX(nr) mnr FROM page_history ".
2808  " WHERE page_id = ".$ilDB->quote($this->getId()).
2809  " AND parent_type = ".$ilDB->quote($this->getParentType()).
2810  " AND nr < ?", array("integer"));
2811  $res = $ilDB->execute($st, array($a_nr));
2812  $row = $ilDB->fetchAssoc($res);
2813  if ($row["mnr"] > 0)
2814  {
2815  $st = $ilDB->prepare("SELECT * FROM page_history ".
2816  " WHERE page_id = ".$ilDB->quote($this->getId()).
2817  " AND parent_type = ".$ilDB->quote($this->getParentType()).
2818  " AND nr = ?", array("integer"));
2819  $res = $ilDB->execute($st, array($row["mnr"]));
2820  $row = $ilDB->fetchAssoc($res);
2821  $ret["previous"] = $row;
2822  }
2823 
2824  // determine next entry
2825  $st = $ilDB->prepare("SELECT MIN(nr) mnr FROM page_history ".
2826  " WHERE page_id = ".$ilDB->quote($this->getId()).
2827  " AND parent_type = ".$ilDB->quote($this->getParentType()).
2828  " AND nr > ?", array("integer"));
2829  $res = $ilDB->execute($st, array($a_nr));
2830  $row = $ilDB->fetchAssoc($res);
2831  if ($row["mnr"] > 0)
2832  {
2833  $st = $ilDB->prepare("SELECT * FROM page_history ".
2834  " WHERE page_id = ".$ilDB->quote($this->getId()).
2835  " AND parent_type = ".$ilDB->quote($this->getParentType()).
2836  " AND nr = ?", array("integer"));
2837  $res = $ilDB->execute($st, array($row["mnr"]));
2838  $row = $ilDB->fetchAssoc($res);
2839  $ret["next"] = $row;
2840  }
2841 
2842  // current
2843  $st = $ilDB->prepare("SELECT * FROM page_history ".
2844  " WHERE page_id = ".$ilDB->quote($this->getId()).
2845  " AND parent_type = ".$ilDB->quote($this->getParentType()).
2846  " AND nr = ?", array("integer"));
2847  $res = $ilDB->execute($st, array($a_nr));
2848  $row = $ilDB->fetchAssoc($res);
2849  $ret["current"] = $row;
2850 
2851 /*
2852  $h_query = "SELECT * FROM page_history ".
2853  " WHERE page_id = ".$ilDB->quote($this->getId()).
2854  " AND parent_type = ".$ilDB->quote($this->getParentType()).
2855  " AND nr = (".
2856  $ilDB->quote($a_nr - 1).",".$ilDB->quote($a_nr).",".$ilDB->quote($a_nr + 1).")".
2857  " ORDER BY hdate DESC";
2858 
2859  $hset = $ilDB->query($h_query);
2860  $ret = array();
2861 
2862  while ($hrec = $hset->fetchRow(DB_FETCHMODE_ASSOC))
2863  {
2864  switch ($hrec["nr"])
2865  {
2866  case ($a_nr - 1):
2867  $ret["previous"] = $hrec;
2868  break;
2869 
2870  case ($a_nr):
2871  $ret["current"] = $hrec;
2872  break;
2873 
2874  case ($a_nr + 1):
2875  $ret["next"] = $hrec;
2876  break;
2877  }
2878  }
2879 */
2880  return $ret;
2881  }
2882 
2883  function addChangeDivClasses($a_hashes)
2884  {
2885  $xpc = xpath_new_context($this->dom);
2886  $path = "/*[1]";
2887  $res =& xpath_eval($xpc, $path);
2888  $rnode = $res->nodeset[0];
2889 
2890 //echo "A";
2891  foreach($a_hashes as $pc_id => $h)
2892  {
2893 //echo "B";
2894  if ($h["change"] != "")
2895  {
2896 //echo "<br>C-".$h["hier_id"]."-".$h["change"]."-";
2897  $dc_node = $this->dom->create_element("DivClass");
2898  $dc_node->set_attribute("HierId", $h["hier_id"]);
2899  $dc_node->set_attribute("Class", "ilEdit".$h["change"]);
2900  $dc_node = $rnode->append_child($dc_node);
2901  }
2902  }
2903  }
2904 
2911  function compareVersion($a_left, $a_right)
2912  {
2913  global $ilDB;
2914 
2915  // get page objects
2916  $l_page = new ilPageObject($this->getParentType(), $this->getId(), $a_left);
2917  $r_page = new ilPageObject($this->getParentType(), $this->getId(), $a_right);
2918 
2919  $l_hashes = $l_page->getPageContentsHashes();
2920  $r_hashes = $r_page->getPageContentsHashes();
2921 
2922  // determine all deleted and changed page elements
2923  foreach ($l_hashes as $pc_id => $h)
2924  {
2925  if (!isset($r_hashes[$pc_id]))
2926  {
2927  $l_hashes[$pc_id]["change"] = "Deleted";
2928  }
2929  else
2930  {
2931  if ($l_hashes[$pc_id]["hash"] != $r_hashes[$pc_id]["hash"])
2932  {
2933  $l_hashes[$pc_id]["change"] = "Modified";
2934  $r_hashes[$pc_id]["change"] = "Modified";
2935 
2936  include_once("./Services/COPage/mediawikidiff/class.WordLevelDiff.php");
2937  // if modified element is a paragraph, highlight changes
2938  if ($l_hashes[$pc_id]["content"] != "" &&
2939  $r_hashes[$pc_id]["content"] != "")
2940  {
2941  $new_left = str_replace("\n", "<br />", $l_hashes[$pc_id]["content"]);
2942  $new_right = str_replace("\n", "<br />", $r_hashes[$pc_id]["content"]);
2943  $wldiff = new WordLevelDiff(array($new_left),
2944  array($new_right));
2945  $new_left = $wldiff->orig();
2946  $new_right = $wldiff->closing();
2947  $l_page->setParagraphContent($l_hashes[$pc_id]["hier_id"], $new_left[0]);
2948  $r_page->setParagraphContent($l_hashes[$pc_id]["hier_id"], $new_right[0]);
2949  }
2950  }
2951  }
2952  }
2953 
2954  // determine all new paragraphs
2955  foreach ($r_hashes as $pc_id => $h)
2956  {
2957  if (!isset($l_hashes[$pc_id]))
2958  {
2959  $r_hashes[$pc_id]["change"] = "New";
2960  }
2961  }
2962 
2963  $l_page->addChangeDivClasses($l_hashes);
2964  $r_page->addChangeDivClasses($r_hashes);
2965 
2966  return array("l_page" => $l_page, "r_page" => $r_page,
2967  "l_changes" => $l_hashes, "r_changes" => $r_hashes);
2968  }
2969 
2973  function increaseViewCnt()
2974  {
2975  global $ilDB;
2976 
2977  $q = "UPDATE page_object ".
2978  " SET view_cnt = view_cnt + 1 ".
2979  " WHERE page_id = ".$ilDB->quote($this->getId()).
2980  " AND parent_type = ".$ilDB->quote($this->getParentType());
2981  $ilDB->query($q);
2982  }
2983 
2991  static function getRecentChanges($a_parent_type, $a_parent_id, $a_period = 30)
2992  {
2993  global $ilDB;
2994 
2995  $page_changes = array();
2996  $q = "SELECT * FROM page_object ".
2997  " WHERE parent_id = ".$ilDB->quote($a_parent_id).
2998  " AND parent_type = ".$ilDB->quote($a_parent_type).
2999  " AND (TO_DAYS(now()) - TO_DAYS(last_change)) <= ".((int)$a_period);
3000  $set = $ilDB->query($q);
3001  while($page = $set->fetchRow(DB_FETCHMODE_ASSOC))
3002  {
3003  $page_changes[] = array("date" => $page["last_change"],
3004  "id" => $page["page_id"], "type" => "page",
3005  "user" => $page["last_change_user"]);
3006  }
3007 
3008  $q = "SELECT * FROM page_history ".
3009  " WHERE parent_id = ".$ilDB->quote($a_parent_id).
3010  " AND parent_type = ".$ilDB->quote($a_parent_type).
3011  " AND (TO_DAYS(now()) - TO_DAYS(hdate)) <= ".((int)$a_period);
3012  $set = $ilDB->query($q);
3013  while ($page = $set->fetchRow(DB_FETCHMODE_ASSOC))
3014  {
3015  $page_changes[] = array("date" => $page["hdate"],
3016  "id" => $page["page_id"], "type" => "hist", "nr" => $page["nr"],
3017  "user" => $page["user"]);
3018  }
3019 
3020  $page_changes = ilUtil::sortArray($page_changes, "date", "desc");
3021 
3022  return $page_changes;
3023  }
3024 
3032  static function getAllPages($a_parent_type, $a_parent_id)
3033  {
3034  global $ilDB;
3035 
3036  $page_changes = array();
3037 
3038  $q = "SELECT * FROM page_object ".
3039  " WHERE parent_id = ".$ilDB->quote($a_parent_id).
3040  " AND parent_type = ".$ilDB->quote($a_parent_type);
3041  $set = $ilDB->query($q);
3042  $pages = array();
3043  while ($page = $set->fetchRow(DB_FETCHMODE_ASSOC))
3044  {
3045  $pages[$page["page_id"]] = array("date" => $page["last_change"],
3046  "id" => $page["page_id"], "user" => $page["last_change_user"]);
3047  }
3048 
3049  return $pages;
3050  }
3051 
3058  static function getNewPages($a_parent_type, $a_parent_id)
3059  {
3060  global $ilDB;
3061 
3062  $pages = array();
3063 
3064  $q = "SELECT * FROM page_object ".
3065  " WHERE parent_id = ".$ilDB->quote($a_parent_id).
3066  " AND parent_type = ".$ilDB->quote($a_parent_type).
3067  " ORDER BY created DESC";
3068  $set = $ilDB->query($q);
3069  while($page = $set->fetchRow(DB_FETCHMODE_ASSOC))
3070  {
3071  if ($page["created"] != "0000-00-00 00:00:00")
3072  {
3073  $pages[] = array("created" => $page["created"],
3074  "id" => $page["page_id"],
3075  "user" => $page["create_user"],
3076  );
3077  }
3078  }
3079 
3080  return $pages;
3081  }
3082 
3089  static function getParentObjectContributors($a_parent_type, $a_parent_id)
3090  {
3091  global $ilDB;
3092 
3093  $contributors = array();
3094  $st = $ilDB->prepare("SELECT last_change_user FROM page_object ".
3095  " WHERE parent_id = ? AND parent_type = ? ".
3096  " AND last_change_user != ?",
3097  array("integer", "text", "integer"));
3098  $set = $ilDB->execute($st, array($a_parent_id, $a_parent_type, 0));
3099 
3100  while ($page = $ilDB->fetchAssoc($set))
3101  {
3102  $contributors[$page["last_change_user"]][$page["page_id"]] = 1;
3103  }
3104 
3105  $st = $ilDB->prepare("SELECT count(*) as cnt, page_id, user FROM page_history ".
3106  " WHERE parent_id = ? AND parent_type = ? AND user != ? ".
3107  " GROUP BY page_id, user ",
3108  array("integer", "text", "integer"));
3109  $set = $ilDB->execute($st, array($a_parent_id, $a_parent_type, 0));
3110  while ($hpage = $ilDB->fetchAssoc($set))
3111  {
3112  $contributors[$hpage["user"]][$hpage["page_id"]] =
3113  $contributors[$hpage["user"]][$hpage["page_id"]] + $hpage["cnt"];
3114  }
3115 
3116  $c = array();
3117  foreach ($contributors as $k => $co)
3118  {
3119  $name = ilObjUser::_lookupName($k);
3120  $c[] = array("user_id" => $k, "pages" => $co,
3121  "lastname" => $name["lastname"], "firstname" => $name["firstname"]);
3122  }
3123 
3124  return $c;
3125  }
3126 
3133  static function getPageContributors($a_parent_type, $a_page_id)
3134  {
3135  global $ilDB;
3136 
3137  $contributors = array();
3138  $st = $ilDB->prepare("SELECT last_change_user FROM page_object ".
3139  " WHERE page_id = ? AND parent_type = ? ".
3140  " AND last_change_user != ?",
3141  array("integer", "text", "integer"));
3142  $set = $ilDB->execute($st, array($a_page_id, $a_parent_type, 0));
3143 
3144  while ($page = $ilDB->fetchAssoc($set))
3145  {
3146  $contributors[$page["last_change_user"]] = 1;
3147  }
3148 
3149  $st = $ilDB->prepare("SELECT count(*) as cnt, page_id, user FROM page_history ".
3150  " WHERE page_id = ? AND parent_type = ? AND user != ? ".
3151  " GROUP BY user ",
3152  array("integer", "text", "integer"));
3153  $set = $ilDB->execute($st, array($a_page_id, $a_parent_type, 0));
3154  while ($hpage = $ilDB->fetchAssoc($set))
3155  {
3156  $contributors[$hpage["user"]] =
3157  $contributors[$hpage["user"]] + $hpage["cnt"];
3158  }
3159 
3160  $c = array();
3161  foreach ($contributors as $k => $co)
3162  {
3163  $name = ilObjUser::_lookupName($k);
3164  $c[] = array("user_id" => $k, "pages" => $co,
3165  "lastname" => $name["lastname"], "firstname" => $name["firstname"]);
3166  }
3167 
3168  return $c;
3169  }
3170 
3174  function writeRenderedContent($a_content, $a_md5)
3175  {
3176  global $ilDB;
3177 
3178  $st = $ilDB->prepareManip("UPDATE page_object ".
3179  " SET rendered_content = ?, render_md5 = ?, rendered_time = now()".
3180  " WHERE page_id = ? AND parent_type = ?",
3181  array("text", "text", "integer", "text"));
3182  $r = $ilDB->execute($st,
3183  array($a_content, $a_md5, $this->getId(), $this->getParentType()));
3184  }
3185 
3193  static function getPagesWithLinks($a_parent_type, $a_parent_id)
3194  {
3195  global $ilDB;
3196 
3197  $page_changes = array();
3198 
3199  $q = "SELECT * FROM page_object ".
3200  " WHERE parent_id = ".$ilDB->quote($a_parent_id).
3201  " AND parent_type = ".$ilDB->quote($a_parent_type).
3202  " AND content LIKE '%IntLink%'";
3203  $set = $ilDB->query($q);
3204  $pages = array();
3205  while ($page = $set->fetchRow(DB_FETCHMODE_ASSOC))
3206  {
3207  $pages[$page["page_id"]] = array("date" => $page["last_change"],
3208  "id" => $page["page_id"], "user" => $page["last_change_user"]);
3209  }
3210 
3211  return $pages;
3212  }
3213 
3214 }
3215 ?>