ILIAS  Release_4_1_x_branch Revision 61804
 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 require_once("./Services/COPage/classes/class.ilWysiwygUtil.php");
6 
18 {
19  var $dom;
20  var $par_node; // node of Paragraph element
21 
25  function init()
26  {
27  $this->setType("par");
28  }
29 
35  function setNode(&$a_node)
36  {
37  parent::setNode($a_node); // this is the PageContent node
38 
39  $childs = $a_node->child_nodes();
40  for ($i=0; $i<count($childs); $i++)
41  {
42  if ($childs[$i]->node_name() == "Paragraph")
43  {
44  $this->par_node = $childs[$i]; //... and this the Paragraph node
45  }
46  }
47  }
48 
49 
55  function createAtNode(&$node)
56  {
57  $this->node = $this->createPageContentNode();
58  $this->par_node =& $this->dom->create_element("Paragraph");
59  $this->par_node =& $this->node->append_child($this->par_node);
60  $this->par_node->set_attribute("Language", "");
61  $node->append_child ($this->node);
62  }
63 
70  function createAfter($node)
71  {
72  $this->node = $this->createPageContentNode(false);
73  if($succ_node = $node->next_sibling())
74  {
75  $this->node = $succ_node->insert_before($this->node, $succ_node);
76  }
77  else
78  {
79  $parent_node = $node->parent_node();
80  $this->node = $parent_node->append_child($this->node);
81  }
82  $this->par_node = $this->dom->create_element("Paragraph");
83  $this->par_node = $this->node->append_child($this->par_node);
84  $this->par_node->set_attribute("Language", "");
85  }
86 
94  function create(&$a_pg_obj, $a_hier_id, $a_pc_id = "")
95  {
96 //echo "-$a_pc_id-";
97  $this->node =& $this->dom->create_element("PageContent");
98  $a_pg_obj->insertContent($this, $a_hier_id, IL_INSERT_AFTER, $a_pc_id);
99  $this->par_node =& $this->dom->create_element("Paragraph");
100  $this->par_node =& $this->node->append_child($this->par_node);
101  $this->par_node->set_attribute("Language", "");
102  }
103 
110  function setText($a_text, $a_auto_split = false)
111  {
112 
113 //var_dump($a_text);
114  if (!is_array($a_text))
115  {
116  $text = array(array("level" => 0, "text" => $a_text));
117  }
118  else
119  {
120  $text = $a_text;
121  }
122 
123  if ($a_auto_split)
124  {
125  $text = $this->autoSplit($a_text);
126  }
127 
128  // DOMXML_LOAD_PARSING, DOMXML_LOAD_VALIDATING, DOMXML_LOAD_RECOVERING
129  $check = "";
130  foreach ($text as $t)
131  {
132  $check.= "<Paragraph>".$t["text"]."</Paragraph>";
133  }
134  /*$temp_dom = domxml_open_mem('<?xml version="1.0" encoding="UTF-8"?><Paragraph>'.$text[0]["text"].'</Paragraph>',
135  DOMXML_LOAD_PARSING, $error);*/
136  $temp_dom = domxml_open_mem('<?xml version="1.0" encoding="UTF-8"?><Paragraph>'.$check.'</Paragraph>',
137  DOMXML_LOAD_PARSING, $error);
138 
139  //$this->text = $a_text;
140  // remove all childs
141  if(empty($error))
142  {
143  $temp_dom = domxml_open_mem('<?xml version="1.0" encoding="UTF-8"?><Paragraph>'.$text[0]["text"].'</Paragraph>',
144  DOMXML_LOAD_PARSING, $error);
145 
146  // delete children of paragraph node
147  $children = $this->par_node->child_nodes();
148  for($i=0; $i<count($children); $i++)
149  {
150  $this->par_node->remove_child($children[$i]);
151  }
152 
153  // copy new content children in paragraph node
154  $xpc = xpath_new_context($temp_dom);
155  $path = "//Paragraph";
156  $res =& xpath_eval($xpc, $path);
157  if (count($res->nodeset) == 1)
158  {
159  $new_par_node =& $res->nodeset[0];
160  $new_childs = $new_par_node->child_nodes();
161 
162  for($i=0; $i<count($new_childs); $i++)
163  {
164  $cloned_child =& $new_childs[$i]->clone_node(true);
165  $this->par_node->append_child($cloned_child);
166  }
167  $orig_characteristic = $this->getCharacteristic();
168 
169  // if headlines are entered and current characteristic is a headline
170  // use no characteristic as standard
171  if ((count($text) > 1) && (substr($orig_characteristic, 0, 8) == "Headline"))
172  {
173  $orig_characteristic = "";
174  }
175  if ($text[0]["level"] > 0)
176  {
177  $this->par_node->set_attribute("Characteristic", 'Headline'.$text[0]["level"]);
178  }
179  }
180 
181  $ok = true;
182 
183  $c_node = $this->node;
184  // add other chunks afterwards
185  for ($i=1; $i<count($text); $i++)
186  {
187  if ($ok)
188  {
189  $next_par = new ilPCParagraph($this->dom);
190  $next_par->createAfter($c_node);
191  $next_par->setLanguage($this->getLanguage());
192  if ($text[$i]["level"] > 0)
193  {
194  $next_par->setCharacteristic("Headline".$text[$i]["level"]);
195  }
196  else
197  {
198  $next_par->setCharacteristic($orig_characteristic);
199  }
200  $ok = $next_par->setText($text[$i]["text"], false);
201  $c_node = $next_par->node;
202  }
203  }
204 
205  return true;
206  }
207  else
208  {
209  // We want the correct number of \n here to have the real lines numbers
210  $text = str_replace("<br>", "\n", $check); // replace <br> with \n to get correct line
211  $text = str_replace("<br/>", "\n", $text);
212  $text = str_replace("<br />", "\n", $text);
213  $text = str_replace("</SimpleListItem>", "</SimpleListItem>\n", $text);
214  $text = str_replace("<SimpleBulletList>", "\n<SimpleBulletList>", $text);
215  $text = str_replace("<SimpleNumberedList>", "\n<SimpleNumberedList>", $text);
216  $text = str_replace("<Paragraph>\n", "<Paragraph>", $text);
217  $text = str_replace("</Paragraph>", "</Paragraph>\n", $text);
218  include_once("./Services/Dom/classes/class.ilDomDocument.php");
219  $doc = new ilDOMDocument();
220  $text = '<?xml version="1.0" encoding="UTF-8"?><Paragraph>'.$text.'</Paragraph>';
221 //echo htmlentities($text);
222  $this->success = $doc->loadXML($text);
223  $error = $doc->errors;
224  $estr = "";
225  foreach ($error as $e)
226  {
227  $e = str_replace(" in Entity", "", $e);
228  $estr.= $e."<br />";
229  }
230  return $estr;
231  }
232  }
233 
239  function getText($a_short_mode = false)
240  {
241  if (is_object($this->par_node))
242  {
243  $content = "";
244  $childs = $this->par_node->child_nodes();
245  for($i=0; $i<count($childs); $i++)
246  {
247  $content .= $this->dom->dump_node($childs[$i]);
248  }
249  return $content;
250  }
251  else
252  {
253  return "";
254  }
255  }
256 
262  function setCharacteristic($a_char)
263  {
264  if (!empty($a_char))
265  {
266  $this->par_node->set_attribute("Characteristic", $a_char);
267  }
268  else
269  {
270  if ($this->par_node->has_attribute("Characteristic"))
271  {
272  $this->par_node->remove_attribute("Characteristic");
273  }
274  }
275  }
276 
282  function getCharacteristic()
283  {
284  if (is_object($this->par_node))
285  {
286  return $this->par_node->get_attribute("Characteristic");
287  }
288  }
289 
290 
294  function setSubCharacteristic($a_char)
295  {
296  if (!empty($a_char))
297  {
298  $this->par_node->set_attribute("SubCharacteristic", $a_char);
299  }
300  else
301  {
302  if ($this->par_node->has_attribute("SubCharacteristic"))
303  {
304  $this->par_node->remove_attribute("SubCharacteristic");
305  }
306  }
307  }
308 
314  function getAutoIndent()
315  {
316  return $this->par_node->get_attribute("AutoIndent");
317  }
318 
319  function setAutoIndent($a_char)
320  {
321  if (!empty($a_char))
322  {
323  $this->par_node->set_attribute("AutoIndent", $a_char);
324  }
325  else
326  {
327  if ($this->par_node->has_attribute("AutoIndent"))
328  {
329  $this->par_node->remove_attribute("AutoIndent");
330  }
331  }
332  }
333 
338  {
339  return $this->par_node->get_attribute("SubCharacteristic");
340  }
341 
346  function setDownloadTitle($a_char)
347  {
348  if (!empty($a_char))
349  {
350  $this->par_node->set_attribute("DownloadTitle", $a_char);
351  }
352  else
353  {
354  if ($this->par_node->has_attribute("DownloadTitle"))
355  {
356  $this->par_node->remove_attribute("DownloadTitle");
357  }
358  }
359  }
360 
364  function getDownloadTitle()
365  {
366  return $this->par_node->get_attribute("DownloadTitle");
367  }
368 
373  function setShowLineNumbers($a_char)
374  {
375  $a_char = empty($a_char)?"n":$a_char;
376 
377  $this->par_node->set_attribute("ShowLineNumbers", $a_char);
378  }
379 
385  {
386  return $this->par_node->get_attribute("ShowLineNumbers");
387  }
388 
392  function setLanguage($a_lang)
393  {
394  $this->par_node->set_attribute("Language", $a_lang);
395  }
396 
400  function getLanguage()
401  {
402  return $this->par_node->get_attribute("Language");
403  }
404 
405  function input2xml($a_text, $a_wysiwyg = 0, $a_handle_lists = true)
406  {
407  return $this->_input2xml($a_text, $this->getLanguage(), $a_wysiwyg, $a_handle_lists);
408  }
409 
413  static function _input2xml($a_text, $a_lang, $a_wysiwyg = 0, $a_handle_lists = true)
414  {
415  $a_text = ilUtil::stripSlashes($a_text, false);
416 
417  // note: the order of the processing steps is crucial
418  // and should be the same as in xml2output() in REVERSE order!
419  $a_text = trim($a_text);
420 
421 //echo "<br>between:".htmlentities($a_text);
422 
423  // mask html
424  $a_text = str_replace("&","&amp;",$a_text);
425  $a_text = str_replace("<","&lt;",$a_text);
426  $a_text = str_replace(">","&gt;",$a_text);
427 
428  // Reconvert PageTurn and BibItemIdentifier
429  $a_text = preg_replace('/&lt;([\s\/]*?PageTurn.*?)&gt;/i',"<$1>",$a_text);
430  $a_text = preg_replace('/&lt;([\s\/]*?BibItemIdentifier.*?)&gt;/i',"<$1>",$a_text);
431 
432 //echo "<br>second:".htmlentities($a_text);
433 
434  // mask curly brackets
435 /*
436 echo htmlentities($a_text);
437  $a_text = str_replace("{", "&#123;", $a_text);
438  $a_text = str_replace("}", "&#125;", $a_text);
439 echo htmlentities($a_text);*/
440  // linefeed to br
441  $a_text = str_replace(chr(13).chr(10),"<br />",$a_text);
442  $a_text = str_replace(chr(13),"<br />", $a_text);
443  $a_text = str_replace(chr(10),"<br />", $a_text);
444 
445  if ($a_handle_lists)
446  {
447  $a_text = ilPCParagraph::input2xmlReplaceLists($a_text);
448  }
449 
450  // bb code to xml
451  $a_text = eregi_replace("\[com\]","<Comment Language=\"".$a_lang."\">",$a_text);
452  $a_text = eregi_replace("\[\/com\]","</Comment>",$a_text);
453  $a_text = eregi_replace("\[emp\]","<Emph>",$a_text);
454  $a_text = eregi_replace("\[\/emp\]","</Emph>",$a_text);
455  $a_text = eregi_replace("\[str\]","<Strong>",$a_text);
456  $a_text = eregi_replace("\[\/str\]","</Strong>",$a_text);
457  $a_text = eregi_replace("\[fn\]","<Footnote>",$a_text);
458  $a_text = eregi_replace("\[\/fn\]","</Footnote>",$a_text);
459  $a_text = eregi_replace("\[quot\]","<Quotation Language=\"".$a_lang."\">",$a_text);
460  $a_text = eregi_replace("\[\/quot\]","</Quotation>",$a_text);
461  $a_text = eregi_replace("\[code\]","<Code>",$a_text);
462  $a_text = eregi_replace("\[\/code\]","</Code>",$a_text);
463  $a_text = eregi_replace("\[acc\]","<Accent>",$a_text);
464  $a_text = eregi_replace("\[\/acc\]","</Accent>",$a_text);
465  $a_text = eregi_replace("\[imp\]","<Important>",$a_text);
466  $a_text = eregi_replace("\[\/imp\]","</Important>",$a_text);
467  $a_text = eregi_replace("\[kw\]","<Keyw>",$a_text);
468  $a_text = eregi_replace("\[\/kw\]","</Keyw>",$a_text);
469 
470  // internal links
471  //$any = "[^\]]*"; // this doesn't work :-(
472  $ws= "[ \t\r\f\v\n]*";
473 
474  while (eregi("\[(iln$ws((inst$ws=$ws([\"0-9])*)?$ws".
475  "((page|chap|term|media|htlm|lm|dbk|glo|frm|exc|tst|svy|webr|chat|cat|crs|grp|file|fold|mep|wiki|sahs|mcst|obj|dfile)$ws=$ws([\"0-9])*)$ws".
476  "(target$ws=$ws(\"(New|FAQ|Media)\"))?$ws(anchor$ws=$ws(\"([^\"])*\"))?$ws))\]", $a_text, $found))
477  {
478  $attribs = ilUtil::attribsToArray($found[2]);
479  $inst_str = $attribs["inst"];
480  // pages
481  if (isset($attribs["page"]))
482  {
483  $tframestr = "";
484  if (!empty($found[10]))
485  {
486  $tframestr = " TargetFrame=\"".$found[10]."\" ";
487  }
488  $ancstr = "";
489  if ($attribs["anchor"] != "")
490  {
491  $ancstr = ' Anchor="'.$attribs["anchor"].'" ';
492  }
493  $a_text = eregi_replace("\[".$found[1]."\]",
494  "<IntLink Target=\"il_".$inst_str."_pg_".$attribs[page]."\" Type=\"PageObject\"".$tframestr.$ancstr.">", $a_text);
495  }
496  // chapters
497  else if (isset($attribs["chap"]))
498  {
499  if (!empty($found[10]))
500  {
501  $tframestr = " TargetFrame=\"".$found[10]."\" ";
502  }
503  else
504  {
505  $tframestr = "";
506  }
507  $a_text = eregi_replace("\[".$found[1]."\]",
508  "<IntLink Target=\"il_".$inst_str."_st_".$attribs[chap]."\" Type=\"StructureObject\"".$tframestr.">", $a_text);
509  }
510  // glossary terms
511  else if (isset($attribs["term"]))
512  {
513  switch ($found[10])
514  {
515  case "New":
516  $tframestr = " TargetFrame=\"New\" ";
517  break;
518 
519  default:
520  $tframestr = " TargetFrame=\"Glossary\" ";
521  break;
522  }
523  $a_text = eregi_replace("\[".$found[1]."\]",
524  "<IntLink Target=\"il_".$inst_str."_git_".$attribs[term]."\" Type=\"GlossaryItem\" $tframestr>", $a_text);
525  }
526  // media object
527  else if (isset($attribs["media"]))
528  {
529  if (!empty($found[10]))
530  {
531  $tframestr = " TargetFrame=\"".$found[10]."\" ";
532  $a_text = eregi_replace("\[".$found[1]."\]",
533  "<IntLink Target=\"il_".$inst_str."_mob_".$attribs[media]."\" Type=\"MediaObject\"".$tframestr.">", $a_text);
534  }
535  else
536  {
537  $a_text = eregi_replace("\[".$found[1]."\]",
538  "<IntLink Target=\"il_".$inst_str."_mob_".$attribs[media]."\" Type=\"MediaObject\"/>", $a_text);
539  }
540  }
541  // direct download file (no repository object)
542  else if (isset($attribs["dfile"]))
543  {
544  $a_text = eregi_replace("\[".$found[1]."\]",
545  "<IntLink Target=\"il_".$inst_str."_dfile_".$attribs[dfile]."\" Type=\"File\">", $a_text);
546  }
547  // repository items (id is ref_id (will be used internally but will
548  // be replaced by object id for export purposes)
549  else if (isset($attribs["lm"]) || isset($attribs["dbk"]) || isset($attribs["glo"])
550  || isset($attribs["frm"]) || isset($attribs["exc"]) || isset($attribs["tst"])
551  || isset($attribs["svy"]) || isset($attribs["obj"]) || isset($attribs['webr'])
552  || isset($attribs["htlm"]) || isset($attribs["chat"]) || isset($attribs["grp"])
553  || isset($attribs["fold"]) || isset($attribs["sahs"]) || isset($attribs["mcst"])
554  || isset($attribs["mep"]) || isset($attribs["wiki"])
555  || isset($attribs["cat"]) || isset($attribs["crs"]) || isset($attribs["file"]))
556  {
557  $obj_id = (isset($attribs["lm"])) ? $attribs["lm"] : $obj_id;
558  $obj_id = (isset($attribs["dbk"])) ? $attribs["dbk"] : $obj_id;
559  $obj_id = (isset($attribs["chat"])) ? $attribs["chat"] : $obj_id;
560  $obj_id = (isset($attribs["glo"])) ? $attribs["glo"] : $obj_id;
561  $obj_id = (isset($attribs["frm"])) ? $attribs["frm"] : $obj_id;
562  $obj_id = (isset($attribs["exc"])) ? $attribs["exc"] : $obj_id;
563  $obj_id = (isset($attribs["htlm"])) ? $attribs["htlm"] : $obj_id;
564  $obj_id = (isset($attribs["tst"])) ? $attribs["tst"] : $obj_id;
565  $obj_id = (isset($attribs["svy"])) ? $attribs["svy"] : $obj_id;
566  $obj_id = (isset($attribs["obj"])) ? $attribs["obj"] : $obj_id;
567  $obj_id = (isset($attribs["webr"])) ? $attribs["webr"] : $obj_id;
568  $obj_id = (isset($attribs["fold"])) ? $attribs["fold"] : $obj_id;
569  $obj_id = (isset($attribs["cat"])) ? $attribs["cat"] : $obj_id;
570  $obj_id = (isset($attribs["crs"])) ? $attribs["crs"] : $obj_id;
571  $obj_id = (isset($attribs["grp"])) ? $attribs["grp"] : $obj_id;
572  $obj_id = (isset($attribs["file"])) ? $attribs["file"] : $obj_id;
573  $obj_id = (isset($attribs["sahs"])) ? $attribs["sahs"] : $obj_id;
574  $obj_id = (isset($attribs["mcst"])) ? $attribs["mcst"] : $obj_id;
575  $obj_id = (isset($attribs["mep"])) ? $attribs["mep"] : $obj_id;
576  $obj_id = (isset($attribs["wiki"])) ? $attribs["wiki"] : $obj_id;
577  //$obj_id = (isset($attribs["obj"])) ? $attribs["obj"] : $obj_id;
578 
579  if ($inst_str == "")
580  {
581  $a_text = eregi_replace("\[".$found[1]."\]",
582  "<IntLink Target=\"il_".$inst_str."_obj_".$obj_id."\" Type=\"RepositoryItem\">", $a_text);
583  }
584  else
585  {
586  $a_text = eregi_replace("\[".$found[1]."\]",
587  "<IntLink Target=\"il_".$inst_str."_".$found[6]."_".$obj_id."\" Type=\"RepositoryItem\">", $a_text);
588  }
589  }
590  else
591  {
592  $a_text = eregi_replace("\[".$found[1]."\]", "[error: iln".$found[1]."]",$a_text);
593  }
594  }
595  while (eregi("\[(iln$ws((inst$ws=$ws([\"0-9])*)?".$ws."media$ws=$ws([\"0-9])*)$ws)/\]", $a_text, $found))
596  {
597  $attribs = ilUtil::attribsToArray($found[2]);
598  $inst_str = $attribs["inst"];
599  $a_text = eregi_replace("\[".$found[1]."/\]",
600  "<IntLink Target=\"il_".$inst_str."_mob_".$attribs[media]."\" Type=\"MediaObject\"/>", $a_text);
601  }
602  $a_text = eregi_replace("\[\/iln\]","</IntLink>",$a_text);
603 
604  // external link
605  $ws= "[ \t\r\f\v\n]*";
606  while (eregi("\[(xln$ws(url$ws=$ws\"([^\"])*\")$ws(target$ws=$ws(\"(Glossary|FAQ|Media)\"))?$ws)\]", $a_text, $found))
607  {
608  $attribs = ilUtil::attribsToArray($found[2]);
609  if (isset($attribs["url"]))
610  {
611  $a2 = ilUtil::attribsToArray($found[4]);
612  $tstr = "";
613  if (in_array($a2["target"], array("FAQ", "Glossary", "Media")))
614  {
615  $tstr = ' TargetFrame="'.$a2["target"].'"';
616  }
617  $a_text = str_replace("[".$found[1]."]", "<ExtLink Href=\"".$attribs["url"]."\"$tstr>", $a_text);
618  }
619  else
620  {
621  $a_text = str_replace("[".$found[1]."]", "[error: xln".$found[1]."]",$a_text);
622  }
623  }
624  $a_text = eregi_replace("\[\/xln\]","</ExtLink>",$a_text);
625 
626  // anchor
627  $ws= "[ \t\r\f\v\n]*";
628  while (eregi("\[(anc$ws(name$ws=$ws\"([^\"])*\")$ws)\]", $a_text, $found))
629  {
630  $attribs = ilUtil::attribsToArray($found[2]);
631  $a_text = str_replace("[".$found[1]."]", "<Anchor Name=\"".$attribs["name"]."\">", $a_text);
632  }
633  $a_text = eregi_replace("\[\/anc\]","</Anchor>",$a_text);
634 //echo htmlentities($a_text);
635  return $a_text;
636  }
637 
645  function input2xmlReplaceLists($a_text)
646  {
647  $rows = explode("<br />", $a_text."<br />");
648 //var_dump($a_text);
649 
650  $old_level = 0;
651 
652  $text = "";
653 
654  foreach ($rows as $row)
655  {
656  $level = 0;
657  if (str_replace("#", "*", substr($row, 0, 3)) == "***")
658  {
659  $level = 3;
660  }
661  else if (str_replace("#", "*", substr($row, 0, 2)) == "**")
662  {
663  $level = 2;
664  }
665  else if (str_replace("#", "*", substr($row, 0, 1)) == "*")
666  {
667  $level = 1;
668  }
669 
670  // end previous line
671  if ($level < $old_level)
672  {
673  for ($i = $old_level; $i > $level; $i--)
674  {
675  $text.= "</SimpleListItem></".$clist[$i].">";
676  }
677  if ($level > 0)
678  {
679  $text.= "</SimpleListItem>";
680  }
681  }
682  else if ($old_level > 0 && $level > 0 && ($level == $old_level))
683  {
684  $text.= "</SimpleListItem>";
685  }
686  else if (($level == $old_level) && $text != "")
687  {
688  $text.= "<br />";
689  }
690 
691  // start next line
692  if ($level > $old_level)
693  {
694  for($i = $old_level + 1; $i <= $level; $i++)
695  {
696  if (substr($row, $i - 1, 1) == "*")
697  {
698  $clist[$i] = "SimpleBulletList";
699  }
700  else
701  {
702  $clist[$i] = "SimpleNumberedList";
703  }
704  $text.= "<".$clist[$i]."><SimpleListItem>";
705  }
706  }
707  else if ($old_level > 0 && $level > 0)
708  {
709  $text.= "<SimpleListItem>";
710  }
711  $text.= substr($row, $level);
712 
713  $old_level = $level;
714  }
715 
716  // remove "<br />" at the end
717  if (substr($text, strlen($text) - 6) == "<br />")
718  {
719  $text = substr($text, 0, strlen($text) - 6);
720  }
721 
722  return $text;
723  }
724 
732  static function xml2outputReplaceLists($a_text)
733  {
734  $segments = ilPCParagraph::segmentString($a_text, array("<SimpleBulletList>", "</SimpleBulletList>",
735  "</SimpleListItem>", "<SimpleListItem>", "<SimpleListItem/>", "<SimpleNumberedList>", "</SimpleNumberedList>"));
736 
737  $current_list = array();
738  $text = "";
739  for ($i=0; $i<= count($segments); $i++)
740  {
741  if ($segments[$i] == "<SimpleBulletList>")
742  {
743  if (count($current_list) == 0)
744  {
745  $list_start = true;
746  }
747  array_push($current_list, "*");
748  $li = false;
749  }
750  else if ($segments[$i] == "<SimpleNumberedList>")
751  {
752  if (count($current_list) == 0)
753  {
754  $list_start = true;
755  }
756  array_push($current_list, "#");
757  $li = false;
758  }
759  else if ($segments[$i] == "</SimpleBulletList>")
760  {
761  array_pop($current_list);
762  $li = false;
763  }
764  else if ($segments[$i] == "</SimpleNumberedList>")
765  {
766  array_pop($current_list);
767  $li = false;
768  }
769  else if ($segments[$i] == "<SimpleListItem>")
770  {
771  $li = true;
772  }
773  else if ($segments[$i] == "</SimpleListItem>")
774  {
775  $li = false;
776  }
777  else if ($segments[$i] == "<SimpleListItem/>")
778  {
779  if ($list_start)
780  {
781  $text.= "<br />";
782  $list_start = false;
783  }
784  foreach($current_list as $list)
785  {
786  $text.= $list;
787  }
788  $text.= "<br />";
789  $li = false;
790  }
791  else
792  {
793  if ($li)
794  {
795  if ($list_start)
796  {
797  $text.= "<br />";
798  $list_start = false;
799  }
800  foreach($current_list as $list)
801  {
802  $text.= $list;
803  }
804  }
805  $text.= $segments[$i];
806  if ($li)
807  {
808  $text.= "<br />";
809  }
810  $li = false;
811  }
812  }
813 
814  // remove trailing <br />, if text ends with list
815  if ($segments[count($segments) - 1] == "</SimpleBulletList>" ||
816  $segments[count($segments) - 1] == "</SimpleNumberedList>" &&
817  substr($text, strlen($text) - 6) == "<br />")
818  {
819  $text = substr($text, 0, strlen($text) - 6);
820  }
821 
822  return $text;
823  }
824 
828  static function segmentString($a_haystack, $a_needles)
829  {
830  $segments = array();
831 
832  $nothing_found = false;
833  while (!$nothing_found)
834  {
835  $nothing_found = true;
836  $found = -1;
837  foreach($a_needles as $needle)
838  {
839  $pos = stripos($a_haystack, $needle);
840  if (is_int($pos) && ($pos < $found || $found == -1))
841  {
842  $found = $pos;
843  $found_needle = $needle;
844  $nothing_found = false;
845  }
846  }
847  if ($found > 0)
848  {
849  $segments[] = substr($a_haystack, 0, $found);
850  $a_haystack = substr($a_haystack, $found);
851  }
852  if ($found > -1)
853  {
854  $segments[] = substr($a_haystack, 0, strlen($found_needle));
855  $a_haystack = substr($a_haystack, strlen($found_needle));
856  }
857  }
858  if ($a_haystack != "")
859  {
860  $segments[] = $a_haystack;
861  }
862 
863  return $segments;
864  }
865 
873  static function xml2output($a_text)
874  {
875  // note: the order of the processing steps is crucial
876  // and should be the same as in input2xml() in REVERSE order!
877 
878  // xml to bb code
879  $any = "[^>]*";
880  $a_text = eregi_replace("<Comment[^>]*>","[com]",$a_text);
881  $a_text = eregi_replace("</Comment>","[/com]",$a_text);
882  $a_text = eregi_replace("<Comment/>","[com][/com]",$a_text);
883  $a_text = eregi_replace("<Emph>","[emp]",$a_text);
884  $a_text = eregi_replace("</Emph>","[/emp]",$a_text);
885  $a_text = eregi_replace("<Emph/>","[emp][/emp]",$a_text);
886  $a_text = eregi_replace("<Strong>","[str]",$a_text);
887  $a_text = eregi_replace("</Strong>","[/str]",$a_text);
888  $a_text = eregi_replace("<Strong/>","[str][/str]",$a_text);
889  $a_text = eregi_replace("<Footnote[^>]*>","[fn]",$a_text);
890  $a_text = eregi_replace("</Footnote>","[/fn]",$a_text);
891  $a_text = eregi_replace("<Footnote/>","[fn][/fn]",$a_text);
892  $a_text = eregi_replace("<Quotation[^>]*>","[quot]",$a_text);
893  $a_text = eregi_replace("</Quotation>","[/quot]",$a_text);
894  $a_text = eregi_replace("<Quotation/>","[quot][/quot]",$a_text);
895  $a_text = eregi_replace("<Code[^>]*>","[code]",$a_text);
896  $a_text = eregi_replace("</Code>","[/code]",$a_text);
897  $a_text = eregi_replace("<Code/>","[code][/code]",$a_text);
898  $a_text = eregi_replace("<Accent>","[acc]",$a_text);
899  $a_text = eregi_replace("</Accent>","[/acc]",$a_text);
900  $a_text = eregi_replace("<Important>","[imp]",$a_text);
901  $a_text = eregi_replace("</Important>","[/imp]",$a_text);
902  $a_text = eregi_replace("<Keyw>","[kw]",$a_text);
903  $a_text = eregi_replace("</Keyw>","[/kw]",$a_text);
904 
905  // replace lists
906  $a_text = ilPCParagraph::xml2outputReplaceLists($a_text);
907 
908  // internal links
909  while (eregi("<IntLink($any)>", $a_text, $found))
910  {
911  $found[0];
912  $attribs = ilUtil::attribsToArray($found[1]);
913  $target = explode("_", $attribs["Target"]);
914  $target_id = $target[count($target) - 1];
915  $inst_str = (!is_int(strpos($attribs["Target"], "__")))
916  ? $inst_str = "inst=\"".$target[1]."\" "
917  : $inst_str = "";
918  switch($attribs["Type"])
919  {
920  case "PageObject":
921  $tframestr = (!empty($attribs["TargetFrame"]))
922  ? " target=\"".$attribs["TargetFrame"]."\""
923  : "";
924  $ancstr = (!empty($attribs["Anchor"]))
925  ? ' anchor="'.$attribs["Anchor"].'"'
926  : "";
927  $a_text = eregi_replace("<IntLink".$found[1].">","[iln ".$inst_str."page=\"".$target_id."\"$tframestr$ancstr]",$a_text);
928  break;
929 
930  case "StructureObject":
931  $tframestr = (!empty($attribs["TargetFrame"]))
932  ? " target=\"".$attribs["TargetFrame"]."\""
933  : "";
934  $a_text = eregi_replace("<IntLink".$found[1].">","[iln ".$inst_str."chap=\"".$target_id."\"$tframestr]",$a_text);
935  break;
936 
937  case "GlossaryItem":
938  $tframestr = (empty($attribs["TargetFrame"]) || $attribs["TargetFrame"] == "Glossary")
939  ? ""
940  : " target=\"".$attribs["TargetFrame"]."\"";
941  $a_text = eregi_replace("<IntLink".$found[1].">","[iln ".$inst_str."term=\"".$target_id."\"".$tframestr."]",$a_text);
942  break;
943 
944  case "MediaObject":
945  if (empty($attribs["TargetFrame"]))
946  {
947  $a_text = eregi_replace("<IntLink".$found[1].">","[iln ".$inst_str."media=\"".$target_id."\"/]",$a_text);
948  }
949  else
950  {
951  $a_text = eregi_replace("<IntLink".$found[1].">","[iln media=\"".$target_id."\"".
952  " target=\"".$attribs["TargetFrame"]."\"]",$a_text);
953  }
954  break;
955 
956  // Repository Item (using ref id)
957  case "RepositoryItem":
958  if ($inst_str == "")
959  {
961  }
962  else
963  {
964  $rtype = $target[count($target) - 2];
965  $target_type = $rtype;
966  }
967  $a_text = eregi_replace("<IntLink".$found[1].">","[iln ".$inst_str."$target_type=\"".$target_id."\"".$tframestr."]",$a_text);
968  break;
969 
970  // Download File (not in repository, Object ID)
971  case "File":
972  $a_text = eregi_replace("<IntLink".$found[1].">","[iln ".$inst_str."dfile=\"".$target_id."\"".$tframestr."]",$a_text);
973  break;
974 
975  default:
976  $a_text = eregi_replace("<IntLink".$found[1].">","[iln]",$a_text);
977  break;
978  }
979  }
980  $a_text = eregi_replace("</IntLink>","[/iln]",$a_text);
981 
982  // external links
983  while (eregi("<ExtLink($any)>", $a_text, $found))
984  {
985  $found[0];
986  $attribs = ilUtil::attribsToArray($found[1]);
987  //$found[1] = str_replace("?", "\?", $found[1]);
988  $tstr = "";
989  if (in_array($attribs["TargetFrame"], array("FAQ", "Glossary", "Media")))
990  {
991  $tstr = ' target="'.$attribs["TargetFrame"].'"';
992  }
993  $a_text = str_replace("<ExtLink".$found[1].">","[xln url=\"".$attribs["Href"]."\"$tstr]",$a_text);
994  }
995  $a_text = eregi_replace("</ExtLink>","[/xln]",$a_text);
996 
997  // anchor
998  while (eregi("<Anchor($any)>", $a_text, $found))
999  {
1000  $found[0];
1001  $attribs = ilUtil::attribsToArray($found[1]);
1002  $a_text = str_replace("<Anchor".$found[1].">","[anc name=\"".$attribs["Name"]."\"]",$a_text);
1003  }
1004  $a_text = eregi_replace("</Anchor>","[/anc]",$a_text);
1005 
1006 
1007  // br to linefeed
1008  $a_text = str_replace("<br />", "\n", $a_text);
1009  $a_text = str_replace("<br/>", "\n", $a_text);
1010 
1011  // prevent curly brackets from being swallowed up by template engine
1012  $a_text = str_replace("{", "&#123;", $a_text);
1013  $a_text = str_replace("}", "&#125;", $a_text);
1014 
1015  // unmask html
1016  $a_text = str_replace("&lt;", "<", $a_text);
1017  $a_text = str_replace("&gt;", ">",$a_text);
1018 
1019  // this is needed to allow html like <tag attribute="value">... in paragraphs
1020  $a_text = str_replace("&quot;", "\"", $a_text);
1021 
1022  // make ampersands in (enabled) html attributes work
1023  // e.g. <a href="foo.php?n=4&t=5">hhh</a>
1024  $a_text = str_replace("&amp;", "&", $a_text);
1025 
1026  // make &gt; and $lt; work to allow (disabled) html descriptions
1027  $a_text = str_replace("&lt;", "&amp;lt;", $a_text);
1028  $a_text = str_replace("&gt;", "&amp;gt;", $a_text);
1029 
1030  return $a_text;
1031  //return str_replace("<br />", chr(13).chr(10), $a_text);
1032  }
1033 
1040  function autoSplit($a_text)
1041  {
1042  $a_text = str_replace ("=<SimpleBulletList>", "=<br /><SimpleBulletList>", $a_text);
1043  $a_text = str_replace ("=<SimpleNumberedList>", "=<br /><SimpleNumberedList>", $a_text);
1044  $a_text = str_replace ("</SimpleBulletList>=", "</SimpleBulletList><br />=", $a_text);
1045  $a_text = str_replace ("</SimpleNumberedList>=", "</SimpleNumberedList><br />=", $a_text);
1046  $a_text = "<br />".$a_text."<br />"; // add preceding and trailing br
1047 
1048  $chunks = array();
1049  $c_text = $a_text;
1050 //echo "0";
1051  while ($c_text != "")
1052  {
1053 //var_dump($c_text); flush();
1054 //echo "1";
1055  $s1 = strpos($c_text, "<br />=");
1056  if (is_int($s1))
1057  {
1058 //echo "2";
1059  $s2 = strpos($c_text, "<br />==");
1060  if (is_int($s2) && $s2 <= $s1)
1061  {
1062 //echo "3";
1063  $s3 = strpos($c_text, "<br />===");
1064  if (is_int($s3) && $s3 <= $s2) // possible level three header
1065  {
1066 //echo "4";
1067  $n = strpos($c_text, "<br />", $s3 + 1);
1068  if ($n > ($s3+9) && substr($c_text, $n-3, 9) == "===<br />")
1069  {
1070 //echo "5";
1071  // found level three header
1072  if ($s3 > 0 || $head != "")
1073  {
1074 //echo "6";
1075  $chunks[] = array("level" => 0,
1076  "text" => $this->removeTrailingBr($head.substr($c_text, 0, $s3)));
1077  $head = "";
1078  }
1079  $chunks[] = array("level" => 3,
1080  "text" => trim(substr($c_text, $s3+9, $n-$s3-12)));
1081  $c_text = $this->handleNextBr(substr($c_text, $n+6));
1082  }
1083  else
1084  {
1085 //echo "7";
1086  $head.= substr($c_text, 0, $n);
1087  $c_text = substr($c_text, $n);
1088  }
1089  }
1090  else // possible level two header
1091  {
1092 //echo "8";
1093  $n = strpos($c_text, "<br />", $s2 + 1);
1094  if ($n > ($s2+8) && substr($c_text, $n-2, 8) == "==<br />")
1095  {
1096 //echo "9";
1097  // found level two header
1098  if ($s2 > 0 || $head != "")
1099  {
1100 //echo "A";
1101  $chunks[] = array("level" => 0,
1102  "text" => $this->removeTrailingBr($head.substr($c_text, 0, $s2)));
1103  $head = "";
1104  }
1105  $chunks[] = array("level" => 2, "text" => trim(substr($c_text, $s2+8, $n-$s2-10)));
1106  $c_text = $this->handleNextBr(substr($c_text, $n+6));
1107  }
1108  else
1109  {
1110 //echo "B";
1111  $head.= substr($c_text, 0, $n);
1112  $c_text = substr($c_text, $n);
1113  }
1114  }
1115  }
1116  else // possible level one header
1117  {
1118 //echo "C";
1119  $n = strpos($c_text, "<br />", $s1 + 1);
1120  if ($n > ($s1+7) && substr($c_text, $n-1, 7) == "=<br />")
1121  {
1122 //echo "D";
1123  // found level one header
1124  if ($s1 > 0 || $head != "")
1125  {
1126 //echo "E";
1127  $chunks[] = array("level" => 0,
1128  "text" => $this->removeTrailingBr($head.substr($c_text, 0, $s1)));
1129  $head = "";
1130  }
1131  $chunks[] = array("level" => 1, "text" => trim(substr($c_text, $s1+7, $n-$s1-8)));
1132  $c_text = $this->handleNextBr(substr($c_text, $n+6));
1133 //echo "<br>ctext:".htmlentities($c_text)."<br>";
1134  }
1135  else
1136  {
1137  $head.= substr($c_text, 0, $n);
1138  $c_text = substr($c_text, $n);
1139 //echo "<br>head:".$head."c_text:".$c_text."<br>";
1140  }
1141  }
1142  }
1143  else
1144  {
1145 //echo "G";
1146  $chunks[] = array("level" => 0, "text" => $head.$c_text);
1147  $head = "";
1148  $c_text = "";
1149  }
1150  }
1151  if (count($chunks) == 0)
1152  {
1153  $chunks[] = array("level" => 0, "text" => "");
1154  }
1155 
1156 
1157  // remove preceding br
1158  if (substr($chunks[0]["text"], 0, 6) == "<br />")
1159  {
1160  $chunks[0]["text"] = substr($chunks[0]["text"], 6);
1161  }
1162 
1163  // remove trailing br
1164  if (substr($chunks[count($chunks) - 1]["text"],
1165  strlen($chunks[count($chunks) - 1]["text"]) - 6, 6) == "<br />")
1166  {
1167  $chunks[count($chunks) - 1]["text"] =
1168  substr($chunks[count($chunks) - 1]["text"], 0, strlen($chunks[count($chunks) - 1]["text"]) - 6);
1169  if ($chunks[count($chunks) - 1]["text"] == "")
1170  {
1171  unset($chunks[count($chunks) - 1]);
1172  }
1173  }
1174  return $chunks;
1175  }
1176 
1180  function handleNextBr($a_str)
1181  {
1182  // do not remove, if next line starts with a "=", otherwise two
1183  // headlines in a row will not be recognized
1184  if (substr($a_str, 0, 6) == "<br />" && substr($a_str, 6, 1) != "=")
1185  {
1186  $a_str = substr($a_str, 6);
1187  }
1188  else
1189  {
1190  // if next line starts with a "=" we need to reinsert the <br />
1191  // otherwise it will not be recognized
1192  if (substr($a_str, 0, 1) == "=")
1193  {
1194  $a_str = "<br />".$a_str;
1195  }
1196  }
1197  return $a_str;
1198  }
1199 
1203  function removeTrailingBr($a_str)
1204  {
1205  if (substr($a_str, strlen($a_str) - 6) == "<br />")
1206  {
1207  $a_str = substr($a_str, 0, strlen($a_str) - 6);
1208  }
1209  return $a_str;
1210  }
1211 
1215  function getType()
1216  {
1217  return ($this->getCharacteristic() == "Code")?"src":parent::getType();
1218  }
1219 
1220 }
1221 ?>