ILIAS  Release_5_0_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.ilPCParagraph.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 require_once("./Services/COPage/classes/class.ilPageContent.php");
5 
17 {
18  var $dom;
19  var $par_node; // node of Paragraph element
20 
24  function init()
25  {
26  $this->setType("par");
27  }
28 
34  function setNode(&$a_node)
35  {
36  parent::setNode($a_node); // this is the PageContent node
37 
38  $childs = $a_node->child_nodes();
39  for ($i=0; $i<count($childs); $i++)
40  {
41  if ($childs[$i]->node_name() == "Paragraph")
42  {
43  $this->par_node = $childs[$i]; //... and this the Paragraph node
44  }
45  }
46  }
47 
48 
54  function createAtNode(&$node)
55  {
56  $this->node = $this->createPageContentNode();
57  $this->par_node =& $this->dom->create_element("Paragraph");
58  $this->par_node =& $this->node->append_child($this->par_node);
59  $this->par_node->set_attribute("Language", "");
60  $node->append_child ($this->node);
61  }
62 
69  {
70  $this->node = $this->createPageContentNode();
71  $this->par_node =& $this->dom->create_element("Paragraph");
72  $this->par_node =& $this->node->append_child($this->par_node);
73  $this->par_node->set_attribute("Language", "");
74  $node->insert_before($this->node, $node);
75  }
76 
83  function createAfter($node)
84  {
85  $this->node = $this->createPageContentNode(false);
86  if($succ_node = $node->next_sibling())
87  {
88  $this->node = $succ_node->insert_before($this->node, $succ_node);
89  }
90  else
91  {
92  $parent_node = $node->parent_node();
93  $this->node = $parent_node->append_child($this->node);
94  }
95  $this->par_node = $this->dom->create_element("Paragraph");
96  $this->par_node = $this->node->append_child($this->par_node);
97  $this->par_node->set_attribute("Language", "");
98  }
99 
107  function create(&$a_pg_obj, $a_hier_id, $a_pc_id = "")
108  {
109 //echo "-$a_pc_id-";
110 //echo "<br>-".htmlentities($a_pg_obj->getXMLFromDom())."-<br><br>"; mk();
111  $this->node =& $this->dom->create_element("PageContent");
112 
113  // this next line kicks out placeholders, if something is inserted
114  $a_pg_obj->insertContent($this, $a_hier_id, IL_INSERT_AFTER, $a_pc_id);
115 
116  $this->par_node =& $this->dom->create_element("Paragraph");
117  $this->par_node =& $this->node->append_child($this->par_node);
118  $this->par_node->set_attribute("Language", "");
119  }
120 
127  function setText($a_text, $a_auto_split = false)
128  {
129 
130 //var_dump($a_text);
131  if (!is_array($a_text))
132  {
133  $text = array(array("level" => 0, "text" => $a_text));
134  }
135  else
136  {
137  $text = $a_text;
138  }
139 
140  if ($a_auto_split)
141  {
142  $text = $this->autoSplit($a_text);
143  }
144 
145  // DOMXML_LOAD_PARSING, DOMXML_LOAD_VALIDATING, DOMXML_LOAD_RECOVERING
146  $check = "";
147  foreach ($text as $t)
148  {
149  $check.= "<Paragraph>".$t["text"]."</Paragraph>";
150  }
151  /*$temp_dom = domxml_open_mem('<?xml version="1.0" encoding="UTF-8"?><Paragraph>'.$text[0]["text"].'</Paragraph>',
152  DOMXML_LOAD_PARSING, $error);*/
153  $temp_dom = domxml_open_mem('<?xml version="1.0" encoding="UTF-8"?><Paragraph>'.$check.'</Paragraph>',
154  DOMXML_LOAD_PARSING, $error);
155 
156  //$this->text = $a_text;
157  // remove all childs
158  if(empty($error))
159  {
160  $temp_dom = domxml_open_mem('<?xml version="1.0" encoding="UTF-8"?><Paragraph>'.$text[0]["text"].'</Paragraph>',
161  DOMXML_LOAD_PARSING, $error);
162 
163  // delete children of paragraph node
164  $children = $this->par_node->child_nodes();
165  for($i=0; $i<count($children); $i++)
166  {
167  $this->par_node->remove_child($children[$i]);
168  }
169 
170  // copy new content children in paragraph node
171  $xpc = xpath_new_context($temp_dom);
172  $path = "//Paragraph";
173  $res =& xpath_eval($xpc, $path);
174  if (count($res->nodeset) == 1)
175  {
176  $new_par_node =& $res->nodeset[0];
177  $new_childs = $new_par_node->child_nodes();
178 
179  for($i=0; $i<count($new_childs); $i++)
180  {
181  $cloned_child =& $new_childs[$i]->clone_node(true);
182  $this->par_node->append_child($cloned_child);
183  }
184  $orig_characteristic = $this->getCharacteristic();
185 
186  // if headlines are entered and current characteristic is a headline
187  // use no characteristic as standard
188  if ((count($text) > 1) && (substr($orig_characteristic, 0, 8) == "Headline"))
189  {
190  $orig_characteristic = "";
191  }
192  if ($text[0]["level"] > 0)
193  {
194  $this->par_node->set_attribute("Characteristic", 'Headline'.$text[0]["level"]);
195  }
196  }
197 
198  $ok = true;
199 
200  $c_node = $this->node;
201  // add other chunks afterwards
202  for ($i=1; $i<count($text); $i++)
203  {
204  if ($ok)
205  {
206  $next_par = new ilPCParagraph($this->getPage());
207  $next_par->createAfter($c_node);
208  $next_par->setLanguage($this->getLanguage());
209  if ($text[$i]["level"] > 0)
210  {
211  $next_par->setCharacteristic("Headline".$text[$i]["level"]);
212  }
213  else
214  {
215  $next_par->setCharacteristic($orig_characteristic);
216  }
217  $ok = $next_par->setText($text[$i]["text"], false);
218  $c_node = $next_par->node;
219  }
220  }
221 
222  return true;
223  }
224  else
225  {
226  // We want the correct number of \n here to have the real lines numbers
227  $text = str_replace("<br>", "\n", $check); // replace <br> with \n to get correct line
228  $text = str_replace("<br/>", "\n", $text);
229  $text = str_replace("<br />", "\n", $text);
230  $text = str_replace("</SimpleListItem>", "</SimpleListItem>\n", $text);
231  $text = str_replace("<SimpleBulletList>", "\n<SimpleBulletList>", $text);
232  $text = str_replace("<SimpleNumberedList>", "\n<SimpleNumberedList>", $text);
233  $text = str_replace("<Paragraph>\n", "<Paragraph>", $text);
234  $text = str_replace("</Paragraph>", "</Paragraph>\n", $text);
235  include_once("./Services/Dom/classes/class.ilDomDocument.php");
236  $doc = new ilDOMDocument();
237  $text = '<?xml version="1.0" encoding="UTF-8"?><Paragraph>'.$text.'</Paragraph>';
238 //echo htmlentities($text);
239  $this->success = $doc->loadXML($text);
240  $error = $doc->errors;
241  $estr = "";
242  foreach ($error as $e)
243  {
244  $e = str_replace(" in Entity", "", $e);
245  $estr.= $e."<br />";
246  }
247  return $estr;
248  }
249  }
250 
256  function getText($a_short_mode = false)
257  {
258  if (is_object($this->par_node))
259  {
260  $content = "";
261  $childs = $this->par_node->child_nodes();
262  for($i=0; $i<count($childs); $i++)
263  {
264  $content .= $this->dom->dump_node($childs[$i]);
265  }
266  return $content;
267  }
268  else
269  {
270  return "";
271  }
272  }
273 
277  function getParagraphSequenceContent($a_pg_obj)
278  {
279  $childs = $this->par_node->parent_node()->parent_node()->child_nodes();
280  $seq = array();
281  $cur_seq = array();
282  $found = false;
283  $pc_id = $this->readPCId();
284  $hier_id = $this->readHierId();
285  for($i=0; $i<count($childs); $i++)
286  {
287  $pchilds = $childs[$i]->child_nodes();
288  if ($pchilds[0]->node_name() == "Paragraph" &&
289  $pchilds[0]->get_attribute("Characteristic") != "Code")
290  {
291  $cur_seq[] = $childs[$i];
292 
293  // check whether this is the sequence of the current paragraph
294  if ($childs[$i]->get_attribute("PCID") == $pc_id &&
295  $childs[$i]->get_attribute("HierId") == $hier_id)
296  {
297  $found = true;
298  }
299 
300  // if this is the current sequenc, get it
301  if ($found)
302  {
303  $seq = $cur_seq;
304  }
305  }
306  else
307  {
308  // non-paragraph element found -> init the current sequence
309  $cur_seq = array();
310  $found = false;
311  }
312  }
313 
314  $content = "";
315  $ids = "###";
316  $id_sep = "";
317  foreach ($seq as $p_node)
318  {
319  $ids.= $id_sep.$p_node->get_attribute("HierId").":".$p_node->get_attribute("PCID");
320  $po = $a_pg_obj->getContentObject($p_node->get_attribute("HierId"),
321  $p_node->get_attribute("PCID"));
322  $s_text = $po->getText();
323  $s_text = $po->xml2output($s_text, true, false);
324  $char = $po->getCharacteristic();
325  if ($char == "")
326  {
327  $char = "Standard";
328  }
329  $s_text = ilPCParagraphGUI::xml2outputJS($s_text, $char, $po->readPCId());
330  $content.= $s_text;
331  $id_sep = ";";
332  }
333  $ids.= "###";
334 
335  return $ids.$content;
336  }
337 
343  function setCharacteristic($a_char)
344  {
345  if (!empty($a_char))
346  {
347  $this->par_node->set_attribute("Characteristic", $a_char);
348  }
349  else
350  {
351  if ($this->par_node->has_attribute("Characteristic"))
352  {
353  $this->par_node->remove_attribute("Characteristic");
354  }
355  }
356  }
357 
363  function getCharacteristic()
364  {
365  if (is_object($this->par_node))
366  {
367  return $this->par_node->get_attribute("Characteristic");
368  }
369  }
370 
371 
375  function setSubCharacteristic($a_char)
376  {
377  if (!empty($a_char))
378  {
379  $this->par_node->set_attribute("SubCharacteristic", $a_char);
380  }
381  else
382  {
383  if ($this->par_node->has_attribute("SubCharacteristic"))
384  {
385  $this->par_node->remove_attribute("SubCharacteristic");
386  }
387  }
388  }
389 
395  function getAutoIndent()
396  {
397  return $this->par_node->get_attribute("AutoIndent");
398  }
399 
400  function setAutoIndent($a_char)
401  {
402  if (!empty($a_char))
403  {
404  $this->par_node->set_attribute("AutoIndent", $a_char);
405  }
406  else
407  {
408  if ($this->par_node->has_attribute("AutoIndent"))
409  {
410  $this->par_node->remove_attribute("AutoIndent");
411  }
412  }
413  }
414 
419  {
420  return $this->par_node->get_attribute("SubCharacteristic");
421  }
422 
427  function setDownloadTitle($a_char)
428  {
429  if (!empty($a_char))
430  {
431  $this->par_node->set_attribute("DownloadTitle", $a_char);
432  }
433  else
434  {
435  if ($this->par_node->has_attribute("DownloadTitle"))
436  {
437  $this->par_node->remove_attribute("DownloadTitle");
438  }
439  }
440  }
441 
445  function getDownloadTitle()
446  {
447  return $this->par_node->get_attribute("DownloadTitle");
448  }
449 
454  function setShowLineNumbers($a_char)
455  {
456  $a_char = empty($a_char)?"n":$a_char;
457 
458  $this->par_node->set_attribute("ShowLineNumbers", $a_char);
459  }
460 
466  {
467  return $this->par_node->get_attribute("ShowLineNumbers");
468  }
469 
473  function setLanguage($a_lang)
474  {
475  $this->par_node->set_attribute("Language", $a_lang);
476  }
477 
481  function getLanguage()
482  {
483  return $this->par_node->get_attribute("Language");
484  }
485 
486  function input2xml($a_text, $a_wysiwyg = 0, $a_handle_lists = true)
487  {
488  return $this->_input2xml($a_text, $this->getLanguage(), $a_wysiwyg, $a_handle_lists);
489  }
490 
494  static function _input2xml($a_text, $a_lang, $a_wysiwyg = 0, $a_handle_lists = true)
495  {
496  if (!$a_wysiwyg)
497  {
498  $a_text = ilUtil::stripSlashes($a_text, false);
499  }
500 
501  if ($a_wysiwyg)
502  {
503  $a_text = str_replace("<br />", chr(10), $a_text);
504  }
505 
506  // note: the order of the processing steps is crucial
507  // and should be the same as in xml2output() in REVERSE order!
508  $a_text = trim($a_text);
509 
510 //echo "<br>between:".htmlentities($a_text);
511 
512  // mask html
513 if (!$a_wysiwyg)
514 {
515  $a_text = str_replace("&","&amp;",$a_text);
516 }
517  $a_text = str_replace("<","&lt;",$a_text);
518  $a_text = str_replace(">","&gt;",$a_text);
519 
520  // Reconvert PageTurn and BibItemIdentifier
521  $a_text = preg_replace('/&lt;([\s\/]*?PageTurn.*?)&gt;/i',"<$1>",$a_text);
522  $a_text = preg_replace('/&lt;([\s\/]*?BibItemIdentifier.*?)&gt;/i',"<$1>",$a_text);
523 
524 //echo "<br>second:".htmlentities($a_text);
525 
526  // mask curly brackets
527 /*
528 echo htmlentities($a_text);
529  $a_text = str_replace("{", "&#123;", $a_text);
530  $a_text = str_replace("}", "&#125;", $a_text);
531 echo htmlentities($a_text);*/
532  // linefeed to br
533  $a_text = str_replace(chr(13).chr(10),"<br />",$a_text);
534  $a_text = str_replace(chr(13),"<br />", $a_text);
535  $a_text = str_replace(chr(10),"<br />", $a_text);
536 
537  if ($a_handle_lists)
538  {
539  $a_text = ilPCParagraph::input2xmlReplaceLists($a_text);
540  }
541 
542  // remove empty tags
543  $atags = array("com", "emp", "str", "fn", "quot", "code", "acc", "imp", "kw");
544  foreach ($atags as $at)
545  {
546  $a_text = str_replace("[".$at."][/".$at."]", "", $a_text);
547  }
548 
549  // bb code to xml
550  $a_text = eregi_replace("\[com\]","<Comment Language=\"".$a_lang."\">",$a_text);
551  $a_text = eregi_replace("\[\/com\]","</Comment>",$a_text);
552  $a_text = eregi_replace("\[emp\]","<Emph>",$a_text);
553  $a_text = eregi_replace("\[\/emp\]","</Emph>",$a_text);
554  $a_text = eregi_replace("\[str\]","<Strong>",$a_text);
555  $a_text = eregi_replace("\[\/str\]","</Strong>",$a_text);
556  $a_text = eregi_replace("\[fn\]","<Footnote>",$a_text);
557  $a_text = eregi_replace("\[\/fn\]","</Footnote>",$a_text);
558  $a_text = eregi_replace("\[quot\]","<Quotation Language=\"".$a_lang."\">",$a_text);
559  $a_text = eregi_replace("\[\/quot\]","</Quotation>",$a_text);
560  $a_text = eregi_replace("\[code\]","<Code>",$a_text);
561  $a_text = eregi_replace("\[\/code\]","</Code>",$a_text);
562  $a_text = eregi_replace("\[acc\]","<Accent>",$a_text);
563  $a_text = eregi_replace("\[\/acc\]","</Accent>",$a_text);
564  $a_text = eregi_replace("\[imp\]","<Important>",$a_text);
565  $a_text = eregi_replace("\[\/imp\]","</Important>",$a_text);
566  $a_text = eregi_replace("\[kw\]","<Keyw>",$a_text);
567  $a_text = eregi_replace("\[\/kw\]","</Keyw>",$a_text);
568 
569  $a_text = self::intLinks2xml($a_text);
570 
571  // external link
572  $ws= "[ \t\r\f\v\n]*";
573  // remove empty external links
574  while (eregi("\[(xln$ws(url$ws=$ws\"([^\"])*\")$ws(target$ws=$ws(\"(Glossary|FAQ|Media)\"))?$ws)\]\[\/xln\]", $a_text, $found))
575  {
576  $a_text = str_replace($found[0], "",$a_text);
577  }
578  while (eregi("\[(xln$ws(url$ws=$ws(([^]])*)))$ws\]\[\/xln\]", $a_text, $found))
579  {
580  $a_text = str_replace($found[0], "",$a_text);
581  }
582  // external links
583  while (eregi("\[(xln$ws(url$ws=$ws\"([^\"])*\")$ws(target$ws=$ws(\"(Glossary|FAQ|Media)\"))?$ws)\]", $a_text, $found))
584  {
585  $attribs = ilUtil::attribsToArray($found[2]);
586  if (isset($attribs["url"]))
587  {
588  $a2 = ilUtil::attribsToArray($found[4]);
589  $tstr = "";
590  if (in_array($a2["target"], array("FAQ", "Glossary", "Media")))
591  {
592  $tstr = ' TargetFrame="'.$a2["target"].'"';
593  }
594  $a_text = str_replace("[".$found[1]."]", "<ExtLink Href=\"".$attribs["url"]."\"$tstr>", $a_text);
595  }
596  else
597  {
598  $a_text = str_replace("[".$found[1]."]", "[error: xln".$found[1]."]",$a_text);
599  }
600  }
601 
602  // ie/tinymce fix for links without "", see bug #8391
603  while (eregi("\[(xln$ws(url$ws=$ws(([^]])*)))$ws\]", $a_text, $found))
604  {
605  if ($found[3] != "")
606  {
607  $a_text = str_replace("[".$found[1]."]", "<ExtLink Href=\"".$found[3]."\">", $a_text);
608  }
609  else
610  {
611  $a_text = str_replace("[".$found[1]."]", "[error: xln".$found[1]."]",$a_text);
612  }
613  }
614  $a_text = eregi_replace("\[\/xln\]","</ExtLink>",$a_text);
615 
616  // anchor
617  $ws= "[ \t\r\f\v\n]*";
618  while (eregi("\[(anc$ws(name$ws=$ws\"([^\"])*\")$ws)\]", $a_text, $found))
619  {
620  $attribs = ilUtil::attribsToArray($found[2]);
621  $a_text = str_replace("[".$found[1]."]", "<Anchor Name=\"".$attribs["name"]."\">", $a_text);
622  }
623  $a_text = eregi_replace("\[\/anc\]","</Anchor>",$a_text);
624 //echo htmlentities($a_text); exit;
625  return $a_text;
626  }
627 
634  static function intLinks2xml($a_text)
635  {
636  global $objDefinition;
637 
638  $rtypes = $objDefinition->getAllRepositoryTypes();
639 
640  // internal links
641  //$any = "[^\]]*"; // this doesn't work :-(
642  $ws= "[ \t\r\f\v\n]*";
643  $ltypes = "page|chap|term|media|obj|dfile|sess|wpage|".implode($rtypes, "|");
644  // empty internal links
645  while (eregi("\[(iln$ws((inst$ws=$ws([\"0-9])*)?$ws".
646  "((".$ltypes.")$ws=$ws([\"0-9])*)$ws".
647  "(target$ws=$ws(\"(New|FAQ|Media)\"))?$ws(anchor$ws=$ws(\"([^\"])*\"))?$ws))\]\[\/iln\]", $a_text, $found))
648  {
649  $a_text = str_replace($found[0], "",$a_text);
650  }
651 
652  while (eregi("\[(iln$ws((inst$ws=$ws([\"0-9])*)?$ws".
653  "((".$ltypes.")$ws=$ws([\"0-9])*)$ws".
654  "(target$ws=$ws(\"(New|FAQ|Media)\"))?$ws(anchor$ws=$ws(\"([^\"])*\"))?$ws))\]", $a_text, $found))
655  {
656  $attribs = ilUtil::attribsToArray($found[2]);
657  $inst_str = $attribs["inst"];
658  // pages
659  if (isset($attribs["page"]))
660  {
661  $tframestr = "";
662  if (!empty($found[10]))
663  {
664  $tframestr = " TargetFrame=\"".$found[10]."\" ";
665  }
666  $ancstr = "";
667  if ($attribs["anchor"] != "")
668  {
669  $ancstr = ' Anchor="'.$attribs["anchor"].'" ';
670  }
671  $a_text = eregi_replace("\[".$found[1]."\]",
672  "<IntLink Target=\"il_".$inst_str."_pg_".$attribs[page]."\" Type=\"PageObject\"".$tframestr.$ancstr.">", $a_text);
673  }
674  // chapters
675  else if (isset($attribs["chap"]))
676  {
677  if (!empty($found[10]))
678  {
679  $tframestr = " TargetFrame=\"".$found[10]."\" ";
680  }
681  else
682  {
683  $tframestr = "";
684  }
685  $a_text = eregi_replace("\[".$found[1]."\]",
686  "<IntLink Target=\"il_".$inst_str."_st_".$attribs[chap]."\" Type=\"StructureObject\"".$tframestr.">", $a_text);
687  }
688  // glossary terms
689  else if (isset($attribs["term"]))
690  {
691  switch ($found[10])
692  {
693  case "New":
694  $tframestr = " TargetFrame=\"New\" ";
695  break;
696 
697  default:
698  $tframestr = " TargetFrame=\"Glossary\" ";
699  break;
700  }
701  $a_text = eregi_replace("\[".$found[1]."\]",
702  "<IntLink Target=\"il_".$inst_str."_git_".$attribs[term]."\" Type=\"GlossaryItem\" $tframestr>", $a_text);
703  }
704  // wiki pages
705  else if (isset($attribs["wpage"]))
706  {
707  $tframestr = "";
708 /* switch ($found[10])
709  {
710  case "New":
711  $tframestr = " TargetFrame=\"New\" ";
712  break;
713 
714  default:
715  $tframestr = " TargetFrame=\"Glossary\" ";
716  break;
717  }*/
718  $a_text = eregi_replace("\[".$found[1]."\]",
719  "<IntLink Target=\"il_".$inst_str."_wpage_".$attribs[wpage]."\" Type=\"WikiPage\" $tframestr>", $a_text);
720  }
721  // media object
722  else if (isset($attribs["media"]))
723  {
724  if (!empty($found[10]))
725  {
726  $tframestr = " TargetFrame=\"".$found[10]."\" ";
727  $a_text = eregi_replace("\[".$found[1]."\]",
728  "<IntLink Target=\"il_".$inst_str."_mob_".$attribs[media]."\" Type=\"MediaObject\"".$tframestr.">", $a_text);
729  }
730  else
731  {
732  $a_text = eregi_replace("\[".$found[1]."\]",
733  "<IntLink Target=\"il_".$inst_str."_mob_".$attribs[media]."\" Type=\"MediaObject\"/>", $a_text);
734  }
735  }
736  // direct download file (no repository object)
737  else if (isset($attribs["dfile"]))
738  {
739  $a_text = eregi_replace("\[".$found[1]."\]",
740  "<IntLink Target=\"il_".$inst_str."_dfile_".$attribs[dfile]."\" Type=\"File\">", $a_text);
741  }
742  // repository items (id is ref_id (will be used internally but will
743  // be replaced by object id for export purposes)
744  else
745  {
746  foreach ($objDefinition->getAllRepositoryTypes() as $t)
747  {
748  if (isset($attribs[$t]))
749  {
750  $obj_id = $attribs[$t];
751  }
752  }
753  if (isset($attribs["obj"]))
754  {
755  $obj_id = $attribs["obj"];
756  }
757 
758  if ($obj_id > 0)
759  {
760  if ($inst_str == "")
761  {
762  $a_text = eregi_replace("\[".$found[1]."\]",
763  "<IntLink Target=\"il_".$inst_str."_obj_".$obj_id."\" Type=\"RepositoryItem\">", $a_text);
764  }
765  else
766  {
767  $a_text = eregi_replace("\[".$found[1]."\]",
768  "<IntLink Target=\"il_".$inst_str."_".$found[6]."_".$obj_id."\" Type=\"RepositoryItem\">", $a_text);
769  }
770  }
771  else
772  {
773  $a_text = eregi_replace("\[".$found[1]."\]", "[error: iln".$found[1]."]",$a_text);
774  }
775  }
776  }
777  while (eregi("\[(iln$ws((inst$ws=$ws([\"0-9])*)?".$ws."media$ws=$ws([\"0-9])*)$ws)/\]", $a_text, $found))
778  {
779  $attribs = ilUtil::attribsToArray($found[2]);
780  $inst_str = $attribs["inst"];
781  $a_text = eregi_replace("\[".$found[1]."/\]",
782  "<IntLink Target=\"il_".$inst_str."_mob_".$attribs[media]."\" Type=\"MediaObject\"/>", $a_text);
783  }
784  $a_text = eregi_replace("\[\/iln\]","</IntLink>",$a_text);
785  return $a_text;
786  }
787 
788 
796  static function input2xmlReplaceLists($a_text)
797  {
798  $rows = explode("<br />", $a_text."<br />");
799 //var_dump($a_text);
800 
801  $old_level = 0;
802 
803  $text = "";
804 
805  foreach ($rows as $row)
806  {
807  $level = 0;
808  if (str_replace("#", "*", substr($row, 0, 3)) == "***")
809  {
810  $level = 3;
811  }
812  else if (str_replace("#", "*", substr($row, 0, 2)) == "**")
813  {
814  $level = 2;
815  }
816  else if (str_replace("#", "*", substr($row, 0, 1)) == "*")
817  {
818  $level = 1;
819  }
820 
821  // end previous line
822  if ($level < $old_level)
823  {
824  for ($i = $old_level; $i > $level; $i--)
825  {
826  $text.= "</SimpleListItem></".$clist[$i].">";
827  }
828  if ($level > 0)
829  {
830  $text.= "</SimpleListItem>";
831  }
832  }
833  else if ($old_level > 0 && $level > 0 && ($level == $old_level))
834  {
835  $text.= "</SimpleListItem>";
836  }
837  else if (($level == $old_level) && $text != "")
838  {
839  $text.= "<br />";
840  }
841 
842  // start next line
843  if ($level > $old_level)
844  {
845  for($i = $old_level + 1; $i <= $level; $i++)
846  {
847  if (substr($row, $i - 1, 1) == "*")
848  {
849  $clist[$i] = "SimpleBulletList";
850  }
851  else
852  {
853  $clist[$i] = "SimpleNumberedList";
854  }
855  $text.= "<".$clist[$i]."><SimpleListItem>";
856  }
857  }
858  else if ($old_level > 0 && $level > 0)
859  {
860  $text.= "<SimpleListItem>";
861  }
862  $text.= substr($row, $level);
863 
864  $old_level = $level;
865  }
866 
867  // remove "<br />" at the end
868  if (substr($text, strlen($text) - 6) == "<br />")
869  {
870  $text = substr($text, 0, strlen($text) - 6);
871  }
872 
873  return $text;
874  }
875 
883  static function xml2outputReplaceLists($a_text)
884  {
885  $segments = ilPCParagraph::segmentString($a_text, array("<SimpleBulletList>", "</SimpleBulletList>",
886  "</SimpleListItem>", "<SimpleListItem>", "<SimpleListItem/>", "<SimpleNumberedList>", "</SimpleNumberedList>"));
887 
888  $current_list = array();
889  $text = "";
890  for ($i=0; $i<= count($segments); $i++)
891  {
892  if ($segments[$i] == "<SimpleBulletList>")
893  {
894  if (count($current_list) == 0)
895  {
896  $list_start = true;
897  }
898  array_push($current_list, "*");
899  $li = false;
900  }
901  else if ($segments[$i] == "<SimpleNumberedList>")
902  {
903  if (count($current_list) == 0)
904  {
905  $list_start = true;
906  }
907  array_push($current_list, "#");
908  $li = false;
909  }
910  else if ($segments[$i] == "</SimpleBulletList>")
911  {
912  array_pop($current_list);
913  $li = false;
914  }
915  else if ($segments[$i] == "</SimpleNumberedList>")
916  {
917  array_pop($current_list);
918  $li = false;
919  }
920  else if ($segments[$i] == "<SimpleListItem>")
921  {
922  $li = true;
923  }
924  else if ($segments[$i] == "</SimpleListItem>")
925  {
926  $li = false;
927  }
928  else if ($segments[$i] == "<SimpleListItem/>")
929  {
930  if ($list_start)
931  {
932  $text.= "<br />";
933  $list_start = false;
934  }
935  foreach($current_list as $list)
936  {
937  $text.= $list;
938  }
939  $text.= "<br />";
940  $li = false;
941  }
942  else
943  {
944  if ($li)
945  {
946  if ($list_start)
947  {
948  $text.= "<br />";
949  $list_start = false;
950  }
951  foreach($current_list as $list)
952  {
953  $text.= $list;
954  }
955  }
956  $text.= $segments[$i];
957  if ($li)
958  {
959  $text.= "<br />";
960  }
961  $li = false;
962  }
963  }
964 
965  // remove trailing <br />, if text ends with list
966  if ($segments[count($segments) - 1] == "</SimpleBulletList>" ||
967  $segments[count($segments) - 1] == "</SimpleNumberedList>" &&
968  substr($text, strlen($text) - 6) == "<br />")
969  {
970  $text = substr($text, 0, strlen($text) - 6);
971  }
972 
973  return $text;
974  }
975 
979  static function segmentString($a_haystack, $a_needles)
980  {
981  $segments = array();
982 
983  $nothing_found = false;
984  while (!$nothing_found)
985  {
986  $nothing_found = true;
987  $found = -1;
988  foreach($a_needles as $needle)
989  {
990  $pos = stripos($a_haystack, $needle);
991  if (is_int($pos) && ($pos < $found || $found == -1))
992  {
993  $found = $pos;
994  $found_needle = $needle;
995  $nothing_found = false;
996  }
997  }
998  if ($found > 0)
999  {
1000  $segments[] = substr($a_haystack, 0, $found);
1001  $a_haystack = substr($a_haystack, $found);
1002  }
1003  if ($found > -1)
1004  {
1005  $segments[] = substr($a_haystack, 0, strlen($found_needle));
1006  $a_haystack = substr($a_haystack, strlen($found_needle));
1007  }
1008  }
1009  if ($a_haystack != "")
1010  {
1011  $segments[] = $a_haystack;
1012  }
1013 
1014  return $segments;
1015  }
1016 
1024  static function xml2output($a_text, $a_wysiwyg = false, $a_replace_lists = true)
1025  {
1026  // note: the order of the processing steps is crucial
1027  // and should be the same as in input2xml() in REVERSE order!
1028 
1029  // xml to bb code
1030  $any = "[^>]*";
1031  $a_text = eregi_replace("<Comment[^>]*>","[com]",$a_text);
1032  $a_text = eregi_replace("</Comment>","[/com]",$a_text);
1033  $a_text = eregi_replace("<Comment/>","[com][/com]",$a_text);
1034  $a_text = eregi_replace("<Emph>","[emp]",$a_text);
1035  $a_text = eregi_replace("</Emph>","[/emp]",$a_text);
1036  $a_text = eregi_replace("<Emph/>","[emp][/emp]",$a_text);
1037  $a_text = eregi_replace("<Strong>","[str]",$a_text);
1038  $a_text = eregi_replace("</Strong>","[/str]",$a_text);
1039  $a_text = eregi_replace("<Strong/>","[str][/str]",$a_text);
1040  $a_text = eregi_replace("<Footnote[^>]*>","[fn]",$a_text);
1041  $a_text = eregi_replace("</Footnote>","[/fn]",$a_text);
1042  $a_text = eregi_replace("<Footnote/>","[fn][/fn]",$a_text);
1043  $a_text = eregi_replace("<Quotation[^>]*>","[quot]",$a_text);
1044  $a_text = eregi_replace("</Quotation>","[/quot]",$a_text);
1045  $a_text = eregi_replace("<Quotation/>","[quot][/quot]",$a_text);
1046  $a_text = eregi_replace("<Code[^>]*>","[code]",$a_text);
1047  $a_text = eregi_replace("</Code>","[/code]",$a_text);
1048  $a_text = eregi_replace("<Code/>","[code][/code]",$a_text);
1049  $a_text = eregi_replace("<Accent>","[acc]",$a_text);
1050  $a_text = eregi_replace("</Accent>","[/acc]",$a_text);
1051  $a_text = eregi_replace("<Important>","[imp]",$a_text);
1052  $a_text = eregi_replace("</Important>","[/imp]",$a_text);
1053  $a_text = eregi_replace("<Keyw>","[kw]",$a_text);
1054  $a_text = eregi_replace("</Keyw>","[/kw]",$a_text);
1055 
1056  // replace lists
1057  if ($a_replace_lists)
1058  {
1059 //echo "<br>".htmlentities($a_text);
1060  $a_text = ilPCParagraph::xml2outputReplaceLists($a_text);
1061 //echo "<br>".htmlentities($a_text);
1062  }
1063 
1064  // internal links
1065  while (eregi("<IntLink($any)>", $a_text, $found))
1066  {
1067  $found[0];
1068  $attribs = ilUtil::attribsToArray($found[1]);
1069  $target = explode("_", $attribs["Target"]);
1070  $target_id = $target[count($target) - 1];
1071  $inst_str = (!is_int(strpos($attribs["Target"], "__")))
1072  ? $inst_str = "inst=\"".$target[1]."\" "
1073  : $inst_str = "";
1074  switch($attribs["Type"])
1075  {
1076  case "PageObject":
1077  $tframestr = (!empty($attribs["TargetFrame"]))
1078  ? " target=\"".$attribs["TargetFrame"]."\""
1079  : "";
1080  $ancstr = (!empty($attribs["Anchor"]))
1081  ? ' anchor="'.$attribs["Anchor"].'"'
1082  : "";
1083  $a_text = eregi_replace("<IntLink".$found[1].">","[iln ".$inst_str."page=\"".$target_id."\"$tframestr$ancstr]",$a_text);
1084  break;
1085 
1086  case "StructureObject":
1087  $tframestr = (!empty($attribs["TargetFrame"]))
1088  ? " target=\"".$attribs["TargetFrame"]."\""
1089  : "";
1090  $a_text = eregi_replace("<IntLink".$found[1].">","[iln ".$inst_str."chap=\"".$target_id."\"$tframestr]",$a_text);
1091  break;
1092 
1093  case "GlossaryItem":
1094  $tframestr = (empty($attribs["TargetFrame"]) || $attribs["TargetFrame"] == "Glossary")
1095  ? ""
1096  : " target=\"".$attribs["TargetFrame"]."\"";
1097  $a_text = eregi_replace("<IntLink".$found[1].">","[iln ".$inst_str."term=\"".$target_id."\"".$tframestr."]",$a_text);
1098  break;
1099 
1100  case "WikiPage":
1101  $tframestr = "";
1102  /*$tframestr = (empty($attribs["TargetFrame"]) || $attribs["TargetFrame"] == "Glossary")
1103  ? ""
1104  : " target=\"".$attribs["TargetFrame"]."\"";*/
1105  $a_text = eregi_replace("<IntLink".$found[1].">","[iln ".$inst_str."wpage=\"".$target_id."\"".$tframestr."]",$a_text);
1106  break;
1107 
1108  case "MediaObject":
1109  if (empty($attribs["TargetFrame"]))
1110  {
1111  $a_text = eregi_replace("<IntLink".$found[1].">","[iln ".$inst_str."media=\"".$target_id."\"/]",$a_text);
1112  }
1113  else
1114  {
1115  $a_text = eregi_replace("<IntLink".$found[1].">","[iln media=\"".$target_id."\"".
1116  " target=\"".$attribs["TargetFrame"]."\"]",$a_text);
1117  }
1118  break;
1119 
1120  // Repository Item (using ref id)
1121  case "RepositoryItem":
1122  if ($inst_str == "")
1123  {
1125  }
1126  else
1127  {
1128  $rtype = $target[count($target) - 2];
1129  $target_type = $rtype;
1130  }
1131  $a_text = eregi_replace("<IntLink".$found[1].">","[iln ".$inst_str."$target_type=\"".$target_id."\"".$tframestr."]",$a_text);
1132  break;
1133 
1134  // Download File (not in repository, Object ID)
1135  case "File":
1136  $a_text = eregi_replace("<IntLink".$found[1].">","[iln ".$inst_str."dfile=\"".$target_id."\"".$tframestr."]",$a_text);
1137  break;
1138 
1139  default:
1140  $a_text = eregi_replace("<IntLink".$found[1].">","[iln]",$a_text);
1141  break;
1142  }
1143  }
1144  $a_text = eregi_replace("</IntLink>","[/iln]",$a_text);
1145 
1146  // external links
1147  while (eregi("<ExtLink($any)>", $a_text, $found))
1148  {
1149  $found[0];
1150  $attribs = ilUtil::attribsToArray($found[1]);
1151  //$found[1] = str_replace("?", "\?", $found[1]);
1152  $tstr = "";
1153  if (in_array($attribs["TargetFrame"], array("FAQ", "Glossary", "Media")))
1154  {
1155  $tstr = ' target="'.$attribs["TargetFrame"].'"';
1156  }
1157  $a_text = str_replace("<ExtLink".$found[1].">","[xln url=\"".$attribs["Href"]."\"$tstr]",$a_text);
1158  }
1159  $a_text = eregi_replace("</ExtLink>","[/xln]",$a_text);
1160 
1161  // anchor
1162  while (eregi("<Anchor($any/)>", $a_text, $found))
1163  {
1164  $found[0];
1165  $attribs = ilUtil::attribsToArray($found[1]);
1166  $a_text = str_replace("<Anchor".$found[1].">","[anc name=\"".$attribs["Name"]."\"][/anc]",$a_text);
1167  }
1168  while (eregi("<Anchor($any)>", $a_text, $found))
1169  {
1170  $found[0];
1171  $attribs = ilUtil::attribsToArray($found[1]);
1172  $a_text = str_replace("<Anchor".$found[1].">","[anc name=\"".$attribs["Name"]."\"]",$a_text);
1173  }
1174  $a_text = eregi_replace("</Anchor>","[/anc]",$a_text);
1175 
1176 
1177  // br to linefeed
1178  if (!$a_wysiwyg)
1179  {
1180  $a_text = str_replace("<br />", "\n", $a_text);
1181  $a_text = str_replace("<br/>", "\n", $a_text);
1182  }
1183 
1184 if (!$a_wysiwyg)
1185 {
1186  // prevent curly brackets from being swallowed up by template engine
1187  $a_text = str_replace("{", "&#123;", $a_text);
1188  $a_text = str_replace("}", "&#125;", $a_text);
1189 
1190  // unmask html
1191  $a_text = str_replace("&lt;", "<", $a_text);
1192  $a_text = str_replace("&gt;", ">",$a_text);
1193 
1194  // this is needed to allow html like <tag attribute="value">... in paragraphs
1195  $a_text = str_replace("&quot;", "\"", $a_text);
1196 
1197  // make ampersands in (enabled) html attributes work
1198  // e.g. <a href="foo.php?n=4&t=5">hhh</a>
1199  $a_text = str_replace("&amp;", "&", $a_text);
1200 
1201  // make &gt; and $lt; work to allow (disabled) html descriptions
1202  $a_text = str_replace("&lt;", "&amp;lt;", $a_text);
1203  $a_text = str_replace("&gt;", "&amp;gt;", $a_text);
1204 }
1205  return $a_text;
1206  //return str_replace("<br />", chr(13).chr(10), $a_text);
1207  }
1208 
1215  function autoSplit($a_text)
1216  {
1217  $a_text = str_replace ("=<SimpleBulletList>", "=<br /><SimpleBulletList>", $a_text);
1218  $a_text = str_replace ("=<SimpleNumberedList>", "=<br /><SimpleNumberedList>", $a_text);
1219  $a_text = str_replace ("</SimpleBulletList>=", "</SimpleBulletList><br />=", $a_text);
1220  $a_text = str_replace ("</SimpleNumberedList>=", "</SimpleNumberedList><br />=", $a_text);
1221  $a_text = "<br />".$a_text."<br />"; // add preceding and trailing br
1222 
1223  $chunks = array();
1224  $c_text = $a_text;
1225 //echo "0";
1226  while ($c_text != "")
1227  {
1228 //var_dump($c_text); flush();
1229 //echo "1";
1230  $s1 = strpos($c_text, "<br />=");
1231  if (is_int($s1))
1232  {
1233 //echo "2";
1234  $s2 = strpos($c_text, "<br />==");
1235  if (is_int($s2) && $s2 <= $s1)
1236  {
1237 //echo "3";
1238  $s3 = strpos($c_text, "<br />===");
1239  if (is_int($s3) && $s3 <= $s2) // possible level three header
1240  {
1241 //echo "4";
1242  $n = strpos($c_text, "<br />", $s3 + 1);
1243  if ($n > ($s3+9) && substr($c_text, $n-3, 9) == "===<br />")
1244  {
1245 //echo "5";
1246  // found level three header
1247  if ($s3 > 0 || $head != "")
1248  {
1249 //echo "6";
1250  $chunks[] = array("level" => 0,
1251  "text" => $this->removeTrailingBr($head.substr($c_text, 0, $s3)));
1252  $head = "";
1253  }
1254  $chunks[] = array("level" => 3,
1255  "text" => trim(substr($c_text, $s3+9, $n-$s3-12)));
1256  $c_text = $this->handleNextBr(substr($c_text, $n+6));
1257  }
1258  else
1259  {
1260 //echo "7";
1261  $head.= substr($c_text, 0, $n);
1262  $c_text = substr($c_text, $n);
1263  }
1264  }
1265  else // possible level two header
1266  {
1267 //echo "8";
1268  $n = strpos($c_text, "<br />", $s2 + 1);
1269  if ($n > ($s2+8) && substr($c_text, $n-2, 8) == "==<br />")
1270  {
1271 //echo "9";
1272  // found level two header
1273  if ($s2 > 0 || $head != "")
1274  {
1275 //echo "A";
1276  $chunks[] = array("level" => 0,
1277  "text" => $this->removeTrailingBr($head.substr($c_text, 0, $s2)));
1278  $head = "";
1279  }
1280  $chunks[] = array("level" => 2, "text" => trim(substr($c_text, $s2+8, $n-$s2-10)));
1281  $c_text = $this->handleNextBr(substr($c_text, $n+6));
1282  }
1283  else
1284  {
1285 //echo "B";
1286  $head.= substr($c_text, 0, $n);
1287  $c_text = substr($c_text, $n);
1288  }
1289  }
1290  }
1291  else // possible level one header
1292  {
1293 //echo "C";
1294  $n = strpos($c_text, "<br />", $s1 + 1);
1295  if ($n > ($s1+7) && substr($c_text, $n-1, 7) == "=<br />")
1296  {
1297 //echo "D";
1298  // found level one header
1299  if ($s1 > 0 || $head != "")
1300  {
1301 //echo "E";
1302  $chunks[] = array("level" => 0,
1303  "text" => $this->removeTrailingBr($head.substr($c_text, 0, $s1)));
1304  $head = "";
1305  }
1306  $chunks[] = array("level" => 1, "text" => trim(substr($c_text, $s1+7, $n-$s1-8)));
1307  $c_text = $this->handleNextBr(substr($c_text, $n+6));
1308 //echo "<br>ctext:".htmlentities($c_text)."<br>";
1309  }
1310  else
1311  {
1312  $head.= substr($c_text, 0, $n);
1313  $c_text = substr($c_text, $n);
1314 //echo "<br>head:".$head."c_text:".$c_text."<br>";
1315  }
1316  }
1317  }
1318  else
1319  {
1320 //echo "G";
1321  $chunks[] = array("level" => 0, "text" => $head.$c_text);
1322  $head = "";
1323  $c_text = "";
1324  }
1325  }
1326  if (count($chunks) == 0)
1327  {
1328  $chunks[] = array("level" => 0, "text" => "");
1329  }
1330 
1331 
1332  // remove preceding br
1333  if (substr($chunks[0]["text"], 0, 6) == "<br />")
1334  {
1335  $chunks[0]["text"] = substr($chunks[0]["text"], 6);
1336  }
1337 
1338  // remove trailing br
1339  if (substr($chunks[count($chunks) - 1]["text"],
1340  strlen($chunks[count($chunks) - 1]["text"]) - 6, 6) == "<br />")
1341  {
1342  $chunks[count($chunks) - 1]["text"] =
1343  substr($chunks[count($chunks) - 1]["text"], 0, strlen($chunks[count($chunks) - 1]["text"]) - 6);
1344  if ($chunks[count($chunks) - 1]["text"] == "")
1345  {
1346  unset($chunks[count($chunks) - 1]);
1347  }
1348  }
1349  return $chunks;
1350  }
1351 
1355  function handleNextBr($a_str)
1356  {
1357  // do not remove, if next line starts with a "=", otherwise two
1358  // headlines in a row will not be recognized
1359  if (substr($a_str, 0, 6) == "<br />" && substr($a_str, 6, 1) != "=")
1360  {
1361  $a_str = substr($a_str, 6);
1362  }
1363  else
1364  {
1365  // if next line starts with a "=" we need to reinsert the <br />
1366  // otherwise it will not be recognized
1367  if (substr($a_str, 0, 1) == "=")
1368  {
1369  $a_str = "<br />".$a_str;
1370  }
1371  }
1372  return $a_str;
1373  }
1374 
1378  function removeTrailingBr($a_str)
1379  {
1380  if (substr($a_str, strlen($a_str) - 6) == "<br />")
1381  {
1382  $a_str = substr($a_str, 0, strlen($a_str) - 6);
1383  }
1384  return $a_str;
1385  }
1386 
1390  function getType()
1391  {
1392  return ($this->getCharacteristic() == "Code")?"src":parent::getType();
1393  }
1394 
1398 
1405  function saveJS($a_pg_obj, $a_content, $a_char, $a_pc_id, $a_insert_at = "")
1406  {
1407  global $ilUser;
1408 
1409  $t = self::handleAjaxContent($a_content);
1410  if ($text === false)
1411  {
1412  return false;
1413  }
1414 
1415  $pc_id = explode(":", $a_pc_id);
1416  $insert_at = explode(":", $a_insert_at);
1417  $t_id = explode(":", $t["id"]);
1418 
1419  // insert new paragraph
1420  if ($a_insert_at != "")
1421  {
1422  $par = new ilPCParagraph($this->getPage());
1423  $par->create($a_pg_obj, $insert_at[0], $insert_at[1]);
1424  }
1425  else
1426  {
1427  $par = $a_pg_obj->getContentObject($pc_id[0], $pc_id[1]);
1428  }
1429 
1430  if ($a_insert_at != "")
1431  {
1432  $pc_id = $a_pg_obj->generatePCId();
1433  $par->writePCId($pc_id);
1434  $this->inserted_pc_id = $pc_id;
1435  }
1436  else
1437  {
1438  $this->inserted_pc_id = $pc_id[1];
1439  }
1440 
1441  $par->setLanguage($ilUser->getLanguage());
1442  $par->setCharacteristic($t["class"]);
1443 
1444  $t2 = $par->input2xml($t["text"], true, false);
1446  $updated = $par->setText($t2, true);
1447 
1448  if ($updated !== true)
1449  {
1450  echo $updated; exit;
1451  return false;
1452  }
1453  $updated = $par->updatePage($a_pg_obj);
1454  //$updated = $a_pg_obj->update();
1455  return $updated;
1456  }
1457 
1464  function getLastSavedPCId($a_pg_obj, $a_as_ajax_str = false)
1465  {
1466  if ($a_as_ajax_str)
1467  {
1468  $a_pg_obj->stripHierIDs();
1469  $a_pg_obj->addHierIds();
1470  $ids = "###";
1471 //var_dump($this->inserted_pc_ids);
1472  $combined = $a_pg_obj->getHierIdsForPCIds(
1473  array($this->inserted_pc_id));
1474  foreach ($combined as $pc_id => $hier_id)
1475  {
1476 //echo "1";
1477  $ids.= $sep.$hier_id.":".$pc_id;
1478  $sep = ";";
1479  }
1480  $ids.= "###";
1481  return $ids;
1482  }
1483 
1484  return $this->inserted_pc_id;
1485  }
1486 
1487 
1491  static function handleAjaxContent($a_content)
1492  {
1493  $a_content = "<dummy>".$a_content."</dummy>";
1494 
1495  $doc = new DOMDocument();
1496 
1497  $content = ilUtil::stripSlashes($a_content, false);
1498 
1499 // $content = str_replace("&lt;", "<", $content);
1500 // $content = str_replace("&gt;", ">", $content);
1501 //echo "<br><br>".htmlentities($content); mk();
1502  $res = $doc->loadXML($content);
1503 
1504  if (!$res)
1505  {
1506  return false;
1507  }
1508 
1509  // convert tags
1510  $xpath = new DOMXpath($doc);
1511 
1512  $elements = $xpath->query("//span");
1513  include_once("./Services/Utilities/classes/class.ilDOM2Util.php");
1514  while (!is_null($elements) && !is_null($element = $elements->item(0)))
1515  {
1516  //$element = $elements->item(0);
1517  $class = $element->getAttribute("class");
1518  if (substr($class, 0, 16) == "ilc_text_inline_")
1519  {
1520  $class_arr = explode(" ", $class);
1521  $cnode = ilDOM2Util::changeName($element, "il".substr($class_arr[0], 16), false);
1522  for ($i = 1; $i < count($class_arr); $i++)
1523  {
1524  $cnode = ilDOM2Util::addParent($cnode, "il".substr($class_arr[$i], 16));
1525  }
1526  }
1527  else
1528  {
1529  ilDOM2Util::replaceByChilds($element);
1530  }
1531 
1532  $elements = $xpath->query("//span");
1533  }
1534 
1535  // convert tags
1536  $xpath = new DOMXpath($doc);
1537  $elements = $xpath->query("/dummy/div");
1538 
1539  $ret = array();
1540  if (!is_null($elements))
1541  {
1542  foreach ($elements as $element)
1543  {
1544  $id = $element->getAttribute("id");
1545  $class = $element->getAttribute("class");
1546  $class = substr($class, 15);
1547  if (trim($class) == "")
1548  {
1549  $class = "Standard";
1550  }
1551 
1552  $text = $doc->saveXML($element);
1553  $text = str_replace("<br/>", "\n", $text);
1554 
1555  // remove wrapping div
1556  $pos = strpos($text, ">");
1557  $text = substr($text, $pos + 1);
1558  $pos = strrpos($text, "<");
1559  $text = substr($text, 0, $pos);
1560 
1561  // todo: remove empty spans <span ...> </span>
1562 
1563  // replace tags by bbcode
1564  foreach (ilPageContentGUI::_getCommonBBButtons() as $bb => $cl)
1565  {
1566  if (!in_array($bb, array("code", "tex", "fn", "xln")))
1567  {
1568  $text = str_replace("<il".$cl.">",
1569  "[".$bb."]", $text);
1570  $text = str_replace("</il".$cl.">",
1571  "[/".$bb."]", $text);
1572  $text = str_replace("<il".$cl."/>", "", $text);
1573  }
1574  }
1575  $text = str_replace(array("<code>", "</code>"),
1576  array("[code]", "[/code]"), $text);
1577 
1578  $text = str_replace("<code/>", "", $text);
1579  $text = str_replace('<ul class="ilc_list_u_BulletedList"/>', "", $text);
1580  $text = str_replace('<ul class="ilc_list_o_NumberedList"/>', "", $text);
1581 
1582  $ret[] = array("text" => $text, "id" => $id, "class" => $class);
1583  }
1584  }
1585 
1586  // we should only have one here!
1587  return $ret[0];
1588  }
1589 
1593  static function handleAjaxContentPost($text)
1594  {
1595  $text = str_replace(array("&lt;ul&gt;", "&lt;/ul&gt;"),
1596  array("<SimpleBulletList>", "</SimpleBulletList>"), $text);
1597  $text = str_replace(array("&lt;ul class='ilc_list_u_BulletedList'&gt;", "&lt;/ul&gt;"),
1598  array("<SimpleBulletList>", "</SimpleBulletList>"), $text);
1599  $text = str_replace(array("&lt;ul class=\"ilc_list_u_BulletedList\"&gt;", "&lt;/ul&gt;"),
1600  array("<SimpleBulletList>", "</SimpleBulletList>"), $text);
1601  $text = str_replace(array("&lt;ol&gt;", "&lt;/ol&gt;"),
1602  array("<SimpleNumberedList>", "</SimpleNumberedList>"), $text);
1603  $text = str_replace(array("&lt;ol class='ilc_list_o_NumberedList'&gt;", "&lt;/ol&gt;"),
1604  array("<SimpleNumberedList>", "</SimpleNumberedList>"), $text);
1605  $text = str_replace(array("&lt;ol class=\"ilc_list_o_NumberedList\"&gt;", "&lt;/ol&gt;"),
1606  array("<SimpleNumberedList>", "</SimpleNumberedList>"), $text);
1607  $text = str_replace(array("&lt;li&gt;", "&lt;/li&gt;"),
1608  array("<SimpleListItem>", "</SimpleListItem>"), $text);
1609  $text = str_replace(array("&lt;li class='ilc_list_item_StandardListItem'&gt;", "&lt;/li&gt;"),
1610  array("<SimpleListItem>", "</SimpleListItem>"), $text);
1611  $text = str_replace(array("&lt;li class=\"ilc_list_item_StandardListItem\"&gt;", "&lt;/li&gt;"),
1612  array("<SimpleListItem>", "</SimpleListItem>"), $text);
1613 
1614  $text = str_replace(array("&lt;li class=\"ilc_list_item_StandardListItem\"/&gt;"),
1615  array("<SimpleListItem></SimpleListItem>"), $text);
1616 
1617  $text = str_replace("<SimpleBulletList><br />", "<SimpleBulletList>", $text);
1618  $text = str_replace("<SimpleNumberedList><br />", "<SimpleNumberedList>", $text);
1619  $text = str_replace("<br /><SimpleBulletList>", "<SimpleBulletList>", $text);
1620  $text = str_replace("<br /><SimpleNumberedList>", "<SimpleNumberedList>", $text);
1621  $text = str_replace("</SimpleBulletList><br />", "</SimpleBulletList>", $text);
1622  $text = str_replace("</SimpleNumberedList><br />", "</SimpleNumberedList>", $text);
1623  $text = str_replace("</SimpleListItem><br />", "</SimpleListItem>", $text);
1624 
1625  return $text;
1626  }
1627 
1635  function updatePage($a_page)
1636  {
1637  $a_page->beforePageContentUpdate($this);
1638 
1639  $ret = $a_page->update();
1640  return $ret;
1641  }
1642 
1649  function autoLinkGlossaries($a_glos)
1650  {
1651  if (is_array($a_glos) && count($a_glos) > 0)
1652  {
1653  include_once("./Modules/Glossary/classes/class.ilGlossaryTerm.php");
1654 
1655  // check which terms occur in the text (we may
1656  // get some false positives due to the strip_tags, but
1657  // we do not want to find strong or list or other stuff
1658  // within the tags
1659  $text = strip_tags($this->getText());
1660  $found_terms = array();
1661  foreach ($a_glos as $glo)
1662  {
1663  if (ilObject::_lookupType($glo) == "glo")
1664  {
1665  $terms = ilGlossaryTerm::getTermList($glo);
1666  foreach ($terms as $t)
1667  {
1668  if (is_int(stripos($text, $t["term"])))
1669  {
1670  $found_terms[$t["id"]] = $t;
1671  }
1672  }
1673  }
1674  }
1675 
1676  // did we find anything? -> modify content
1677  if (count($found_terms) > 0)
1678  {
1679  self::linkTermsInDom($this->dom, $found_terms, $this->par_node);
1680  }
1681  }
1682  }
1683 
1690  protected static function linkTermsInDom($a_dom, $a_terms, $a_par_node = null)
1691  {
1692  // sort terms by their length (shortes first)
1693  // to prevent that nested tags are builded
1694  foreach ($a_terms as $k => $t)
1695  {
1696  $a_terms[$k]["termlength"] = strlen($t["term"]);
1697  }
1698  $a_terms = ilUtil::sortArray($a_terms, "termlength", "asc", true);
1699 
1700 
1701  if ($a_dom instanceof php4DOMDocument)
1702  {
1703  $a_dom = $a_dom->myDOMDocument;
1704  }
1705  if ($a_par_node instanceof php4DOMElement)
1706  {
1707  $a_par_node = $a_par_node->myDOMNode;
1708  }
1709 
1710  $xpath = new DOMXPath($a_dom);
1711 
1712  if ($a_par_node == null)
1713  {
1714  $parnodes = $xpath->query('//Paragraph');
1715  }
1716  else
1717  {
1718  $parnodes = $xpath->query('//Paragraph', $a_par_node);
1719  }
1720 
1721 
1722  include_once("./Services/Utilities/classes/class.ilStr.php");
1723 
1724  foreach ($parnodes as $parnode)
1725  {
1726  $textnodes = $xpath->query('//text()', $parnode);
1727  foreach ($textnodes as $node)
1728  {
1729  $p = $node->getNodePath();
1730 
1731  // we do not change text nodes inside of links
1732  if (!is_int(strpos($p, "/IntLink")) &&
1733  !is_int(strpos($p, "/ExtLink")))
1734  {
1735  $node_val = $node->nodeValue;
1736 
1737  // all terms
1738  foreach ($a_terms as $t)
1739  {
1740  $pos = ilStr::strIPos($node_val, $t["term"]);
1741 
1742  // if term found
1743  while (is_int($pos))
1744  {
1745  // check if the string is not included in another word
1746  // note that []
1747  $valid_limiters = array("", " ","&nbsp;", ".", ",", ":", ";", "!", "?", "\"", "'", "(", ")");
1748  $b = ($pos > 0)
1749  ? ilStr::subStr($node_val, $pos - 1, 1)
1750  : "";
1751  $a = ilStr::subStr($node_val, $pos + ilStr::strLen($t["term"]), 1);
1752  if ((in_array($b, $valid_limiters) || htmlentities($b, null, 'utf-8') == "&nbsp;")&& in_array($a, $valid_limiters))
1753  {
1754  $mid = '[iln term="'.$t["id"].'"]'.
1755  ilStr::subStr($node_val, $pos, ilStr::strLen($t["term"])).
1756  "[/iln]";
1757 
1758  $node_val = ilStr::subStr($node_val, 0, $pos).
1759  $mid.
1760  ilStr::subStr($node_val, $pos + ilStr::strLen($t["term"]))
1761  ;
1762 
1763  $pos+= ilStr::strLen($mid);
1764  }
1765  else
1766  {
1767  $pos+= ilStr::strLen($t["term"]);
1768  }
1769  $pos = ilStr::strIPos($node_val, $t["term"], $pos);
1770  }
1771 
1772  // insert [iln] tags
1773  }
1774 
1775  $node->nodeValue = $node_val;
1776  }
1777 
1778  // var_dump($p);
1779  // var_dump($node->nodeValue);
1780  }
1781 
1782 
1783  // dump paragraph node
1784  $text = $a_dom->saveXML($parnode);
1785  $text = substr($text, 0, strlen($text) - strlen("</Paragraph>"));
1786  $text = substr($text, strpos($text, ">") + 1);
1787 
1788  // replace [iln] by tags with xml representation
1789  $text = self::intLinks2xml($text);
1790 
1791  // "set text"
1792  $temp_dom = domxml_open_mem('<?xml version="1.0" encoding="UTF-8"?><Paragraph>'.$text.'</Paragraph>',
1793  DOMXML_LOAD_PARSING, $error);
1794  $temp_dom = $temp_dom->myDOMDocument;
1795 
1796  if(empty($error))
1797  {
1798  // delete children of paragraph node
1799  $children = $parnode->childNodes;
1800  while ($parnode->hasChildNodes())
1801  {
1802  $parnode->removeChild($parnode->firstChild);
1803  }
1804 
1805  // copy new content children in paragraph node
1806  $xpath_temp = new DOMXPath($temp_dom);
1807  $temp_pars = $xpath_temp->query("//Paragraph");
1808 
1809  foreach ($temp_pars as $new_par_node)
1810  {
1811  $new_childs = $new_par_node->childNodes;
1812 
1813  foreach($new_childs as $new_child)
1814  {
1815  //$cloned_child = $new_child->cloneNode(true);
1816  $cloned_child = $a_dom->importNode($new_child, true);
1817  $parnode->appendChild($cloned_child);
1818  }
1819  }
1820  }
1821  }
1822  }
1823 
1824 
1831  static function autoLinkGlossariesPage($a_page, $a_terms)
1832  {
1833  $a_page->buildDom();
1834  $a_dom = $a_page->getDom();
1835 
1836  self::linkTermsInDom($a_dom, $a_terms);
1837 
1838  $a_page->update();
1839  }
1840 
1849  static function afterPageUpdate($a_page, DOMDocument $a_domdoc, $a_xml, $a_creation)
1850  {
1851  // pc paragraph
1852  self::saveMetaKeywords($a_page, $a_domdoc);
1853  self::saveAnchors($a_page, $a_domdoc);
1854  }
1855 
1861  static function beforePageDelete($a_page)
1862  {
1863  // delete anchors
1864  self::_deleteAnchors($a_page->getParentType(), $a_page->getId(), $a_page->getLanguage());
1865  }
1866 
1875  static function afterPageHistoryEntry($a_page, DOMDocument $a_old_domdoc, $a_old_xml, $a_old_nr)
1876  {
1877  }
1878 
1884  function saveAnchors($a_page, $a_domdoc)
1885  {
1886  self::_deleteAnchors($a_page->getParentType(), $a_page->getId(), $a_page->getLanguage());
1887 
1888  // get all anchors
1889  $xpath = new DOMXPath($a_domdoc);
1890  $nodes = $xpath->query('//Anchor');
1891  $saved = array();
1892  foreach ($nodes as $node)
1893  {
1894  $name = $node->getAttribute("Name");
1895  if (trim($name) != "" && !in_array($name, $saved))
1896  {
1897  self::_saveAnchor($a_page->getParentType(), $a_page->getId(), $a_page->getLanguage(), $name);
1898  $saved[] = $name;
1899  }
1900  }
1901 
1902  }
1903 
1907  static function _deleteAnchors($a_parent_type, $a_page_id, $a_page_lang)
1908  {
1909  global $ilDB;
1910 
1911  $ilDB->manipulate("DELETE FROM page_anchor WHERE ".
1912  " page_parent_type = ".$ilDB->quote($a_parent_type, "text").
1913  " AND page_id = ".$ilDB->quote($a_page_id, "integer").
1914  " AND page_lang = ".$ilDB->quote($a_page_lang, "text")
1915  );
1916  }
1917 
1921  static function _saveAnchor($a_parent_type, $a_page_id, $a_page_lang, $a_anchor_name)
1922  {
1923  global $ilDB;
1924 
1925  $ilDB->manipulate("INSERT INTO page_anchor ".
1926  "(page_parent_type, page_id, page_lang, anchor_name) VALUES (".
1927  $ilDB->quote($a_parent_type, "text").",".
1928  $ilDB->quote($a_page_id, "integer").",".
1929  $ilDB->quote($a_page_lang, "text").",".
1930  $ilDB->quote($a_anchor_name, "text").
1931  ")");
1932  }
1933 
1937  static function _readAnchors($a_parent_type, $a_page_id, $a_page_lang = "-")
1938  {
1939  global $ilDB;
1940 
1941  $and_lang = ($a_page_lang != "")
1942  ? " AND page_lang = ".$ilDB->quote($a_page_lang, "text")
1943  : "";
1944 
1945  $set = $ilDB->query("SELECT * FROM page_anchor ".
1946  " WHERE page_parent_type = ".$ilDB->quote($a_parent_type, "text").
1947  " AND page_id = ".$ilDB->quote($a_page_id, "integer").
1948  $and_lang
1949  );
1950  $anchors = array();
1951  while ($rec = $ilDB->fetchAssoc($set))
1952  {
1953  $anchors[] = $rec["anchor_name"];
1954  }
1955  return $anchors;
1956  }
1957 
1964  function saveMetaKeywords($a_page, $a_domdoc)
1965  {
1966  // not nice, should be set by context per method
1967  if ($a_page->getParentType() == "gdf" ||
1968  $a_page->getParentType() == "lm")
1969  {
1970  // get existing keywords
1971  $keywords = array();
1972 
1973  // find all Keyw tags
1974  $xpath = new DOMXPath($a_domdoc);
1975  $nodes = $xpath->query('//Keyw');
1976  foreach($nodes as $node)
1977  {
1978  $k = trim(strip_tags($node->nodeValue));
1979  if (!in_array($k, $keywords))
1980  {
1981  $keywords[] = $k;
1982  }
1983  }
1984 
1985  $meta_type = ($a_page->getParentType() == "gdf")
1986  ? "gdf"
1987  : "pg";
1988  $meta_rep_id = $a_page->getParentId();
1989  $meta_id = $a_page->getId();
1990 
1991  include_once("./Services/MetaData/classes/class.ilMD.php");
1992  $md_obj = new ilMD($meta_rep_id, $meta_id, $meta_type);
1993  $mkeywords = array();
1994  $lang = "";
1995  if(is_object($md_section = $md_obj->getGeneral()))
1996  {
1997  foreach($ids = $md_section->getKeywordIds() as $id)
1998  {
1999  $md_key = $md_section->getKeyword($id);
2000  $mkeywords[] = strtolower($md_key->getKeyword());
2001  if ($lang == "")
2002  {
2003  $lang = $md_key->getKeywordLanguageCode();
2004  }
2005  }
2006  if ($lang == "")
2007  {
2008  foreach($ids = $md_section->getLanguageIds() as $id)
2009  {
2010  $md_lang = $md_section->getLanguage($id);
2011  if ($lang == "")
2012  {
2013  $lang = $md_lang->getLanguageCode();
2014  }
2015  }
2016  }
2017  foreach ($keywords as $k)
2018  {
2019  if (!in_array(strtolower($k), $mkeywords))
2020  {
2021  if (trim($k) != "" && $lang != "")
2022  {
2023  $md_key = $md_section->addKeyword();
2024  $md_key->setKeyword(ilUtil::stripSlashes($k));
2025  $md_key->setKeywordLanguage(new ilMDLanguageItem($lang));
2026  $md_key->save();
2027  }
2028  $mkeywords[] = strtolower($k);
2029  }
2030  }
2031  }
2032  }
2033  }
2034 
2035 }
2036 ?>