ILIAS  Release_5_0_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.ilPCTable.php
Go to the documentation of this file.
1 <?php
2 
3 /* Copyright (c) 1998-2010 ILIAS open source, Extended GPL, see docs/LICENSE */
4 
5 require_once("./Services/COPage/classes/class.ilPageContent.php");
6 
17 class ilPCTable extends ilPageContent
18 {
19  var $dom;
20  var $tab_node;
21 
22 
26  function init()
27  {
28  $this->setType("tab");
29  }
30 
31  function setNode(&$a_node)
32  {
33  parent::setNode($a_node); // this is the PageContent node
34  $this->tab_node =& $a_node->first_child(); // this is the Table node
35  }
36 
37  function create(&$a_pg_obj, $a_hier_id, $a_pc_id = "")
38  {
39  $this->node = $this->createPageContentNode();
40  $a_pg_obj->insertContent($this, $a_hier_id, IL_INSERT_AFTER, $a_pc_id);
41  $this->tab_node =& $this->dom->create_element("Table");
42  $this->tab_node =& $this->node->append_child($this->tab_node);
43  $this->tab_node->set_attribute("Language", "");
44  }
45 
46  function &addRow () {
47  $new_tr =& $this->dom->create_element("TableRow");
48  $new_tr = &$this->tab_node->append_child($new_tr);
49  return $new_tr;
50  }
51 
52  function &addCell (&$aRow, $a_data = "", $a_lang = "")
53  {
54  $new_td =& $this->dom->create_element("TableData");
55  $new_td =& $aRow->append_child($new_td);
56 
57  // insert data if given
58  if ($a_data != "")
59  {
60  $new_pg =& $this->createPageContentNode(false);
61  $new_par =& $this->dom->create_element("Paragraph");
62  $new_par =& $new_pg->append_child($new_par);
63  $new_par->set_attribute("Language", $a_lang);
64  $new_par->set_attribute("Characteristic", "TableContent");
65  $new_par->set_content($a_data);
66  $new_td->append_child ($new_pg);
67  }
68 
69  return $new_td;
70  }
71 
75  function addRows($a_nr_rows, $a_nr_cols)
76  {
77  for ($i=1; $i<=$a_nr_rows; $i++)
78  {
79  $aRow = $this->addRow();
80  for ($j=1; $j<=$a_nr_cols; $j++)
81  {
82  $this->addCell($aRow);
83  }
84  }
85  }
86 
90  function importSpreadsheet($a_lang, $a_data)
91  {
92  str_replace($a_data, "\r", "\n");
93  str_replace($a_data, "\n\n", "\n");
94  $target_rows = array();
95  $rows = explode("\n", $a_data);
96 
97  // get maximum of cols in a row and
98  // put data in target_row arrays
99  foreach($rows as $row)
100  {
101  $cells = explode("\t", $row);
102  $max_cols = ($max_cols > count($cells))
103  ? $max_cols
104  : count($cells);
105  $target_rows[] = $cells;
106  }
107 
108  // iterate target row arrays and insert data
109  foreach($target_rows as $row)
110  {
111  $aRow = $this->addRow();
112  for ($j=0; $j<$max_cols; $j++)
113  {
114  // mask html
115  $data = str_replace("&","&amp;", $row[$j]);
116  $data = str_replace("<","&lt;", $data);
117  $data = str_replace(">","&gt;", $data);
118 
119  $this->addCell($aRow, $data, $a_lang);
120  }
121  }
122  }
123 
127  function getLanguage()
128  {
129  return $this->getTableAttribute("Language");
130  }
131 
137  function setLanguage($a_lang)
138  {
139  if($a_lang != "")
140  {
141  $this->setTableAttribute("Language", $a_lang);
142  }
143  }
144 
148  function getWidth()
149  {
150  return $this->getTableAttribute("Width");
151  }
152 
158  function setWidth($a_width)
159  {
160  $this->setTableAttribute("Width", $a_width);
161  }
162 
166  function getBorder()
167  {
168  return $this->getTableAttribute("Border");
169  }
170 
176  function setBorder($a_border)
177  {
178  $this->setTableAttribute("Border", $a_border);
179  }
180 
184  function getCellSpacing()
185  {
186  return $this->getTableAttribute("CellSpacing");
187  }
188 
194  function setCellSpacing($a_spacing)
195  {
196  $this->setTableAttribute("CellSpacing", $a_spacing);
197  }
198 
202  function getCellPadding()
203  {
204  return $this->getTableAttribute("CellPadding");
205  }
206 
212  function setCellPadding($a_padding)
213  {
214  $this->setTableAttribute("CellPadding", $a_padding);
215  }
216 
220  function setHorizontalAlign($a_halign)
221  {
222  $this->tab_node->set_attribute("HorizontalAlign", $a_halign);
223  }
224 
229  {
230  return $this->getTableAttribute("HorizontalAlign");
231  }
232 
236  function setTDWidth($a_hier_id, $a_width, $a_pc_id = "")
237  {
238  $xpc = xpath_new_context($this->dom);
239 
240  if ($a_pc_id == "")
241  {
242  $path = "//TableData[@HierId = '".$a_hier_id."']";
243  }
244  else
245  {
246  $path = "//TableData[@PCID = '".$a_pc_id."']";
247  }
248  $res =& xpath_eval($xpc, $path);
249 
250  if (count($res->nodeset) == 1)
251  {
252  if($a_width != "")
253  {
254  $res->nodeset[0]->set_attribute("Width", $a_width);
255  }
256  else
257  {
258  if ($res->nodeset[0]->has_attribute("Width"))
259  {
260  $res->nodeset[0]->remove_attribute("Width");
261  }
262  }
263  }
264  }
265 
269  function setTDSpans($a_colspans, $a_rowspans)
270  {
271  $y = 0;
272  $rows = $this->tab_node->child_nodes();
273  foreach($rows as $row)
274  {
275  if ($row->node_name() == "TableRow")
276  {
277  $x = 0;
278  $cells = $row->child_nodes();
279  foreach($cells as $cell)
280  {
281  if ($cell->node_name() == "TableData")
282  {
283  $ckey = $cell->get_attribute("HierId").":".$cell->get_attribute("PCID");
284  if((int) $a_colspans[$ckey] > 1)
285  {
286  $cell->set_attribute("ColSpan", (int) $a_colspans[$ckey]);
287  }
288  else
289  {
290  if ($cell->has_attribute("ColSpan"))
291  {
292  $cell->remove_attribute("ColSpan");
293  }
294  }
295  if((int) $a_rowspans[$ckey] > 1)
296  {
297  $cell->set_attribute("RowSpan", (int) $a_rowspans[$ckey]);
298  }
299  else
300  {
301  if ($cell->has_attribute("RowSpan"))
302  {
303  $cell->remove_attribute("RowSpan");
304  }
305  }
306  }
307  $x++;
308  }
309  $y++;
310  }
311  }
312  $this->fixHideAndSpans();
313  }
314 
320  function fixHideAndSpans()
321  {
322 
323  // first: get max x and y
324  $max_x = $max_y = 0;
325  $y = 0;
326  $rows = $this->tab_node->child_nodes();
327 
328  foreach($rows as $row)
329  {
330  if ($row->node_name() == "TableRow")
331  {
332  $x = 0;
333  $cells = $row->child_nodes();
334  foreach($cells as $cell)
335  {
336  if ($cell->node_name() == "TableData")
337  {
338  $max_x = max ($max_x, $x);
339  $max_y = max ($max_y, $y);
340  }
341  $x++;
342  }
343  $y++;
344  }
345  }
346 
347  // second: fix hidden/colspans for all cells
348  $y = 0;
349  $rows = $this->tab_node->child_nodes();
350  foreach($rows as $row)
351  {
352  if ($row->node_name() == "TableRow")
353  {
354  $x = 0;
355  $cells = $row->child_nodes();
356  foreach($cells as $cell)
357  {
358  if ($cell->node_name() == "TableData")
359  {
360  $cspan = max(1, (int) $cell->get_attribute("ColSpan"));
361  $rspan = max(1, (int) $cell->get_attribute("RowSpan"));
362 
363  // if col or rowspan is to high: reduce it to the max
364  if ($cspan > $max_x - $x + 1)
365  {
366  $cell->set_attribute("ColSpan", $max_x - $x + 1);
367  $cspan = $max_x - $x + 1;
368  }
369  if ($rspan > $max_y - $y + 1)
370  {
371  $cell->set_attribute("RowSpan", $max_y - $y + 1);
372  $rspan = $max_y - $y + 1;
373  }
374 
375  // check hidden status
376  if ($this->checkCellHidden($colspans, $rowspans, $x, $y))
377  {
378  // hidden: set hidden flag, remove col and rowspan
379  $cell->set_attribute("Hidden", "Y");
380  $cspan = 1;
381  $rspan = 1;
382  if ($cell->has_attribute("ColSpan"))
383  {
384  $cell->remove_attribute("ColSpan");
385  }
386  if ($cell->has_attribute("RowSpan"))
387  {
388  $cell->remove_attribute("RowSpan");
389  }
390  $this->makeEmptyCell($cell);
391  }
392  else
393  {
394  // not hidden: remove hidden flag if existing
395  if ($cell->has_attribute("Hidden"))
396  {
397  $cell->remove_attribute("Hidden");
398  }
399  }
400 
401  $colspans[$x][$y] = $cspan;
402  $rowspans[$x][$y] = $rspan;
403  }
404  $x++;
405  }
406  $y++;
407  }
408  }
409 
410  }
411 
412 
416  function makeEmptyCell($td_node)
417  {
418  // delete children of paragraph node
419  $children = $td_node->child_nodes();
420  for($i=0; $i<count($children); $i++)
421  {
422  $td_node->remove_child($children[$i]);
423  }
424  }
425 
429  function checkCellHidden($colspans, $rowspans, $x, $y)
430  {
431  for ($i = 0; $i<=$x; $i++)
432  {
433  for ($j = 0; $j<=$y; $j++)
434  {
435  if ($i != $x || $j != $y)
436  {
437  if ((($i + $colspans[$i][$j] > $x) &&
438  ($j + $rowspans[$i][$j] > $y)))
439  {
440  return true;
441  }
442  }
443  }
444  }
445  return false;
446  }
447 
453  function getAllCellClasses()
454  {
455  $classes = array();
456  $rows = $this->tab_node->child_nodes();
457  foreach($rows as $row)
458  {
459  if ($row->node_name() == "TableRow")
460  {
461  $cells = $row->child_nodes();
462  foreach($cells as $cell)
463  {
464  if ($cell->node_name() == "TableData")
465  {
466  $classes[$cell->get_attribute("HierId").":".$cell->get_attribute("PCID")]
467  = $cell->get_attribute("Class");
468  }
469  }
470  }
471  }
472 
473  return $classes;
474  }
475 
482  {
483  $classes = array();
484  $rows = $this->tab_node->child_nodes();
485  foreach($rows as $row)
486  {
487  if ($row->node_name() == "TableRow")
488  {
489  $cells = $row->child_nodes();
490  foreach($cells as $cell)
491  {
492  if ($cell->node_name() == "TableData")
493  {
494  $classes[$cell->get_attribute("HierId").":".$cell->get_attribute("PCID")]
495  = $cell->get_attribute("HorizontalAlign");
496  }
497  }
498  }
499  }
500 
501  return $classes;
502  }
503 
509  function getAllCellSpans()
510  {
511  $spans = array();
512  $rows = $this->tab_node->child_nodes();
513  $y = 0;
514  $max_x = 0;
515  $max_y = 0;
516  foreach($rows as $row)
517  {
518  if ($row->node_name() == "TableRow")
519  {
520  $x = 0;
521  $cells = $row->child_nodes();
522  foreach($cells as $cell)
523  {
524  if ($cell->node_name() == "TableData")
525  {
526  $spans[$cell->get_attribute("HierId").":".$cell->get_attribute("PCID")]
527  = array("x" => $x, "y" => $y, "colspan" => $cell->get_attribute("ColSpan"),
528  "rowspan" => $cell->get_attribute("RowSpan"));
529  $max_x = max($max_x, $x);
530  $max_y = max($max_y, $y);
531  }
532  $x++;
533  }
534  $y++;
535  }
536  }
537  foreach ($spans as $k => $v)
538  {
539  $spans[$k]["max_x"] = $max_x;
540  $spans[$k]["max_y"] = $max_y;
541  }
542 
543  return $spans;
544  }
545 
551  function getAllCellWidths()
552  {
553  $widths = array();
554  $rows = $this->tab_node->child_nodes();
555  foreach($rows as $row)
556  {
557  if ($row->node_name() == "TableRow")
558  {
559  $cells = $row->child_nodes();
560  foreach($cells as $cell)
561  {
562  if ($cell->node_name() == "TableData")
563  {
564  $widths[$cell->get_attribute("HierId").":".$cell->get_attribute("PCID")]
565  = $cell->get_attribute("Width");
566  }
567  }
568  }
569  }
570 
571  return $widths;
572  }
573 
577  function setTDClass($a_hier_id, $a_class, $a_pc_id = "")
578  {
579  $xpc = xpath_new_context($this->dom);
580  if ($a_pc_id == "")
581  {
582  $path = "//TableData[@HierId = '".$a_hier_id."']";
583  }
584  else
585  {
586  $path = "//TableData[@PCID = '".$a_pc_id."']";
587  }
588  $res =& xpath_eval($xpc, $path);
589  if (count($res->nodeset) == 1)
590  {
591  if($a_class != "")
592  {
593  $res->nodeset[0]->set_attribute("Class", $a_class);
594  }
595  else
596  {
597  if ($res->nodeset[0]->has_attribute("Class"))
598  {
599  $res->nodeset[0]->remove_attribute("Class");
600  }
601  }
602  }
603  }
604 
608  function setTDAlignment($a_hier_id, $a_class, $a_pc_id = "")
609  {
610  $xpc = xpath_new_context($this->dom);
611  if ($a_pc_id == "")
612  {
613  $path = "//TableData[@HierId = '".$a_hier_id."']";
614  }
615  else
616  {
617  $path = "//TableData[@PCID = '".$a_pc_id."']";
618  }
619  $res =& xpath_eval($xpc, $path);
620  if (count($res->nodeset) == 1)
621  {
622  if($a_class != "")
623  {
624  $res->nodeset[0]->set_attribute("HorizontalAlign", $a_class);
625  }
626  else
627  {
628  if ($res->nodeset[0]->has_attribute("HorizontalAlign"))
629  {
630  $res->nodeset[0]->remove_attribute("HorizontalAlign");
631  }
632  }
633  }
634  }
635 
639  function getCaption()
640  {
641  $hier_id = $this->getHierId();
642  if(!empty($hier_id))
643  {
644  $xpc = xpath_new_context($this->dom);
645  $path = "//PageContent[@HierId = '".$hier_id."']/Table/Caption";
646  $res =& xpath_eval($xpc, $path);
647 
648  if (count($res->nodeset) == 1)
649  {
650  return $res->nodeset[0]->get_content();
651  }
652  }
653  }
654 
658  function getCaptionAlign()
659  {
660  $hier_id = $this->getHierId();
661  if(!empty($hier_id))
662  {
663  $xpc = xpath_new_context($this->dom);
664  $path = "//PageContent[@HierId = '".$hier_id."']/Table/Caption";
665  $res =& xpath_eval($xpc, $path);
666  if (count($res->nodeset) == 1)
667  {
668  return $res->nodeset[0]->get_attribute("Align");
669  }
670  }
671  }
672 
676  function setCaption($a_content, $a_align)
677  {
678  if ($a_content != "")
679  {
680  ilDOMUtil::setFirstOptionalElement($this->dom, $this->tab_node, "Caption",
681  array("Summary", "TableRow"), $a_content,
682  array("Align" => $a_align));
683  }
684  else
685  {
686  ilDOMUtil::deleteAllChildsByName($this->tab_node, array("Caption"));
687  }
688  }
689 
690 
692  /*echo "importing table attributes";
693  var_dump($tableNode);*/
694  if ($node->has_attributes ())
695  {
696  foreach($node->attributes() as $n)
697  {
698 
699  switch (strtolower($n->node_name ())) {
700  case "border":
701  $this->setBorder ($this->extractText($n));
702  break;
703  case "align":
704  $this->setHorizontalAlign(ucfirst(strtolower($this->extractText($n))));
705  break;
706  case "cellspacing":
707  $this->setCellSpacing($this->extractText($n));
708  break;
709  case "cellpadding":
710  $this->setCellPadding($this->extractText($n));
711  break;
712  case "width":
713  $this->setWidth($this->extractText($n));
714  break;
715 
716  }
717 
718  }
719  }
720  }
721 
722 
723  function importCellAttributes (&$node, &$par) {
724  /*echo "importing table attributes";
725  var_dump($tableNode);*/
726  if ($node->has_attributes ())
727  {
728  foreach($node->attributes() as $n)
729  {
730 
731  switch (strtolower($n->node_name ())) {
732  case "class":
733  $par->set_attribute("Class", $this->extractText($n));
734  break;
735  case "width":
736  $par->set_attribute("Width", $this->extractText($n));
737  break;
738  }
739 
740  }
741  }
742  }
743 
744 
745  function importRow ($lng, &$node) {
746  /*echo "add Row";
747  var_dump($node);*/
748 
749  $aRow = $this->addRow();
750 
751  if ($node->has_child_nodes())
752  {
753  foreach($node->child_nodes() as $n)
754  {
755  if ($n->node_type() == XML_ELEMENT_NODE &&
756  strcasecmp($n->node_name (), "td") == 0)
757  {
758  $this->importCell ($lng, $n, $aRow);
759  }
760  }
761  }
762  }
763 
764  function importCell ($lng, &$cellNode, &$aRow) {
765  /*echo "add Cell";
766  var_dump($cellNode);*/
767  $aCell = $this->addCell($aRow);
768  $par = new ilPCParagraph($this->getPage());
769  $par->createAtNode($aCell);
770  $par->setText($par->input2xml($this->extractText($cellNode)));
771  $par->setCharacteristic("TableContent");
772  $par->setLanguage($lng);
773  $this->importCellAttributes($cellNode, $aCell);
774  }
775 
776  function extractText (&$node) {
777  $owner_document = $node->owner_document ();
778  $children = $node->child_nodes();
779  $total_children = count($children);
780  for ($i = 0; $i < $total_children; $i++){
781  $cur_child_node = $children[$i];
782  $output .= $owner_document->dump_node($cur_child_node);
783  }
784  return $output;
785  }
786 
787  function importHtml ($lng, $htmlTable) {
788  $dummy = ilUtil::stripSlashes($htmlTable, false);
789  //echo htmlentities($dummy);
790  $dom = @domxml_open_mem($dummy,DOMXML_LOAD_PARSING, $error);
791 
792  if ($dom)
793  {
794  $xpc = @xpath_new_context($dom);
795  // extract first table object
796  $path = "//table[1] | //Table[1]";
797  $res = @xpath_eval($xpc, $path);
798 
799  if (count($res->nodeset) == 0)
800  {
801  $error = "Could not find a table root node";
802  }
803 
804  if (empty ($error))
805  {
806  for($i = 0; $i < count($res->nodeset); $i++)
807  {
808  $node = $res->nodeset[$i];
809 
810  $this->importTableAttributes ($node);
811 
812  if ($node->has_child_nodes())
813  {
814  foreach($node->child_nodes() as $n)
815  {
816  if ($n->node_type() == XML_ELEMENT_NODE &&
817  strcasecmp($n->node_name (), "tr") == 0)
818  {
819 
820  $this->importRow ($lng, $n);
821  }
822  }
823  }
824  }
825  }
826  $dom->free ();
827  }
828  if (is_array($error)) {
829  $errmsg = "";
830  foreach ($error as $errorline) { # Loop through all errors
831  $errmsg .= "[" . $errorline['line'] . ", " . $errorline['col'] . "]: ".$errorline['errormessage']." at Node '". $errorline['nodename'] . "'<br />";
832  }
833  }else
834  {
835  $errmsg = $error;
836  }
837 
838  if (empty ($errmsg)) {
839  return true;
840  }
841 
842  $_SESSION["message"] = $errmsg;
843  return false;
844  }
845 
849  function setFirstRowStyle($a_class)
850  {
851  $childs = $this->tab_node->child_nodes();
852  foreach($childs as $child)
853  {
854  if ($child->node_name() == "TableRow")
855  {
856  $gchilds = $child->child_nodes();
857  foreach($gchilds as $gchild)
858  {
859  if ($gchild->node_name() == "TableData")
860  {
861  $gchild->set_attribute("Class", $a_class);
862  }
863  }
864  return;
865  }
866  }
867  }
868 
874  function setClass($a_class)
875  {
876  $this->setTableAttribute("Class", $a_class);
877  }
878 
884  function getClass()
885  {
886  return $this->getTableAttribute("Class");
887  }
888 
894  function setTemplate($a_template)
895  {
896  $this->setTableAttribute("Template", $a_template);
897  }
898 
904  function getTemplate()
905  {
906  return $this->getTableAttribute("Template");
907  }
908 
914  function setHeaderRows($a_nr)
915  {
916  $this->setTableAttribute("HeaderRows", $a_nr);
917  }
918 
924  function getHeaderRows()
925  {
926  return $this->getTableAttribute("HeaderRows");
927  }
928 
934  function setFooterRows($a_nr)
935  {
936  $this->setTableAttribute("FooterRows", $a_nr);
937  }
938 
944  function getFooterRows()
945  {
946  return $this->getTableAttribute("FooterRows");
947  }
948 
954  function setHeaderCols($a_nr)
955  {
956  $this->setTableAttribute("HeaderCols", $a_nr);
957  }
958 
964  function getHeaderCols()
965  {
966  return $this->getTableAttribute("HeaderCols");
967  }
968 
974  function setFooterCols($a_nr)
975  {
976  $this->setTableAttribute("FooterCols", $a_nr);
977  }
978 
984  function getFooterCols()
985  {
986  return $this->getTableAttribute("FooterCols");
987  }
988 
995  protected function setTableAttribute($a_attr, $a_value)
996  {
997  if (!empty($a_value))
998  {
999  $this->tab_node->set_attribute($a_attr, $a_value);
1000  }
1001  else
1002  {
1003  if ($this->tab_node->has_attribute($a_attr))
1004  {
1005  $this->tab_node->remove_attribute($a_attr);
1006  }
1007  }
1008  }
1009 
1015  function getTableAttribute($a_attr)
1016  {
1017  if (is_object($this->tab_node))
1018  {
1019  return $this->tab_node->get_attribute($a_attr);
1020  }
1021  }
1022 
1027  static function getLangVars()
1028  {
1029  return array("ed_insert_dtable", "ed_insert_atable","ed_new_row_after", "ed_new_row_before",
1030  "ed_new_col_after", "ed_new_col_before", "ed_delete_col",
1031  "ed_delete_row", "ed_edit_data", "ed_row_up", "ed_row_down",
1032  "ed_col_left", "ed_col_right");
1033  }
1034 
1035 
1042  static function handleCopiedContent(DOMDocument $a_domdoc, $a_self_ass = true, $a_clone_mobs = false)
1043  {
1044  $xpath = new DOMXPath($a_domdoc);
1045  $nodes = $xpath->query("//Table");
1046  foreach($nodes as $node)
1047  {
1048  $node->removeAttribute("Id");
1049  }
1050  }
1051 }
1052 
1053 ?>