ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
class.ilPCTable.php
Go to the documentation of this file.
1<?php
2
25{
26 public function init(): void
27 {
28 $this->setType("tab");
29 }
30
31 public function create(
32 ilPageObject $a_pg_obj,
33 string $a_hier_id,
34 string $a_pc_id = ""
35 ): void {
37 $a_hier_id,
38 $a_pc_id,
39 "Table",
40 ["Language" => ""]
41 );
42 }
43
44 public function addRow(): DOMNode
45 {
46 $new_tr = $this->dom_doc->createElement("TableRow");
47 $new_tr = $this->getChildNode()->appendChild($new_tr);
48 return $new_tr;
49 }
50
51 public function addCell(
52 DOMNode $aRow,
53 string $a_data = "",
54 string $a_lang = ""
55 ): DOMNode {
56 $new_td = $this->dom_doc->createElement("TableData");
57 $new_td = $aRow->appendChild($new_td);
58
59 // insert data if given
60 if ($a_data != "") {
61 $new_pg = $this->getNewPageContentNode();
62 $new_par = $this->dom_doc->createElement("Paragraph");
63 $new_par = $new_pg->appendChild($new_par);
64 $new_par->setAttribute("Language", $a_lang);
65 $new_par->setAttribute("Characteristic", "TableContent");
66 $this->dom_util->setContent($new_par, $a_data);
67 $new_td->appendChild($new_pg);
68 }
69
70 return $new_td;
71 }
72
76 public function getCellText(int $i, int $j): string
77 {
78 $cell_par = $this->getCellNode($i, $j, false);
79 if (!is_null($cell_par)) {
80 $content = "";
81 foreach ($cell_par->childNodes as $c) {
82 $content .= $this->dom_util->dump($c);
83 }
84 return $content;
85 } else {
86 return "";
87 }
88 }
89
93 public function getCellNode(int $i, int $j, bool $create_if_not_exists = false): ?DOMNode
94 {
95 $path = "//PageContent[@HierId='" . $this->getHierId() . "']" .
96 "/Table/TableRow[" . ($i + 1) . "]/TableData[" . ($j + 1) . "]/PageContent[1]/Paragraph[1]";
97 $nodes = $this->dom_util->path($this->dom_doc, $path);
98 if (!is_null($nodes->item(0))) {
99 return $nodes->item(0);
100 } else { // no node -> delete all childs and create paragraph
101 if (!$create_if_not_exists) {
102 return null;
103 }
104 $path2 = "//PageContent[@HierId='" . $this->getHierId() . "']" .
105 "/Table/TableRow[" . ($i + 1) . "]/TableData[" . ($j + 1) . "]";
106 $nodes2 = $this->dom_util->path($this->dom_doc, $path2);
107
108 $td_node = $nodes2->item(0);
109
110 if (!is_null($td_node)) {
111 // delete children of paragraph node
112 $this->dom_util->deleteAllChilds($td_node);
113
114 // create page content and paragraph node here.
115 $pc_node = $this->getNewPageContentNode();
116 $pc_node = $td_node->appendChild($pc_node);
117 $par_node = $this->dom_doc->createElement("Paragraph");
118 $par_node = $pc_node->appendChild($par_node);
119 $par_node->setAttribute("Characteristic", "TableContent");
120 $par_node->setAttribute(
121 "Language",
122 $this->getLanguage()
123 );
124
125 return $par_node;
126 }
127 }
128
129 return null;
130 }
131
135 public function getTableDataNode(int $i, int $j): ?DOMElement
136 {
137 $path = "//PageContent[@HierId='" . $this->getHierId() . "']" .
138 "/Table/TableRow[$i+1]/TableData[$j+1]";
139 $nodes = $this->dom_util->path($this->dom_doc, $path);
140
141 if (count($nodes) > 0) {
142 return $nodes->item(0);
143 }
144 return null;
145 }
146
150 public function addRows(int $a_nr_rows, int $a_nr_cols): void
151 {
152 for ($i = 1; $i <= $a_nr_rows; $i++) {
153 $aRow = $this->addRow();
154 for ($j = 1; $j <= $a_nr_cols; $j++) {
155 $this->addCell($aRow);
156 }
157 }
158 }
159
163 public function importSpreadsheet(
164 string $a_lang,
165 string $a_data
166 ): void {
167 $max_cols = 0;
168
169 str_replace($a_data, "\r", "\n");
170 str_replace($a_data, "\n\n", "\n");
171 $target_rows = array();
172 $rows = explode("\n", $a_data);
173
174 // get maximum of cols in a row and
175 // put data in target_row arrays
176 foreach ($rows as $row) {
177 $cells = explode("\t", $row);
178 if (count($cells) === 1) {
179 $cells = explode(";", $row);
180 }
181 $max_cols = ($max_cols > count($cells))
182 ? $max_cols
183 : count($cells);
184 $target_rows[] = $cells;
185 }
186
187 // iterate target row arrays and insert data
188 foreach ($target_rows as $row) {
189 $aRow = $this->addRow();
190 for ($j = 0; $j < $max_cols; $j++) {
191 // mask html
192 $data = str_replace("&", "&amp;", ($row[$j] ?? ""));
193 $data = str_replace("<", "&lt;", $data);
194 $data = str_replace(">", "&gt;", $data);
195
196 $this->addCell($aRow, $data, $a_lang);
197 }
198 }
199 }
200
201 public function getLanguage(): string
202 {
203 return $this->getTableAttribute("Language");
204 }
205
206 public function setLanguage(string $a_lang): void
207 {
208 if ($a_lang != "") {
209 $this->setTableAttribute("Language", $a_lang);
210 }
211 }
212
213 public function getWidth(): string
214 {
215 return $this->getTableAttribute("Width");
216 }
217
218 public function setWidth(string $a_width): void
219 {
220 $this->setTableAttribute("Width", $a_width);
221 }
222
223 public function getBorder(): string
224 {
225 return $this->getTableAttribute("Border");
226 }
227
228 public function setBorder(string $a_border): void
229 {
230 $this->setTableAttribute("Border", $a_border);
231 }
232
233 public function getCellSpacing(): string
234 {
235 return $this->getTableAttribute("CellSpacing");
236 }
237
238 public function setCellSpacing(string $a_spacing): void
239 {
240 $this->setTableAttribute("CellSpacing", $a_spacing);
241 }
242
243 public function getCellPadding(): string
244 {
245 return $this->getTableAttribute("CellPadding");
246 }
247
248 public function setCellPadding(string $a_padding): void
249 {
250 $this->setTableAttribute("CellPadding", $a_padding);
251 }
252
253 public function setHorizontalAlign(string $a_halign): void
254 {
255 $this->getChildNode()->setAttribute("HorizontalAlign", $a_halign);
256 }
257
258 public function getHorizontalAlign(): string
259 {
260 return $this->getTableAttribute("HorizontalAlign");
261 }
262
266 public function setTDWidth(
267 string $a_hier_id,
268 string $a_width,
269 string $a_pc_id = ""
270 ): void {
271 if ($a_pc_id == "") {
272 $path = "//TableData[@HierId = '" . $a_hier_id . "']";
273 } else {
274 $path = "//TableData[@PCID = '" . $a_pc_id . "']";
275 }
276 $nodes = $this->dom_util->path($this->dom_doc, $path);
277
278 if (count($nodes) == 1) {
279 if ($a_width != "") {
280 $nodes->item(0)->setAttribute("Width", $a_width);
281 } else {
282 if ($nodes->item(0)->hasAttribute("Width")) {
283 $nodes->item(0)->removeAttribute("Width");
284 }
285 }
286 }
287 }
288
289 public function setTDSpans(
290 array $a_colspans,
291 array $a_rowspans
292 ): void {
293 $y = 0;
294 $rows = $this->getChildNode()->childNodes;
295 foreach ($rows as $row) {
296 if ($row->nodeName == "TableRow") {
297 $x = 0;
298 $cells = $row->childNodes;
299 foreach ($cells as $cell) {
300 if ($cell->nodeName == "TableData") {
301 $ckey = $cell->getAttribute("HierId") . ":" . $cell->getAttribute("PCID");
302 if ((int) ($a_colspans[$ckey] ?? 0) > 1) {
303 $cell->setAttribute("ColSpan", (int) $a_colspans[$ckey]);
304 } else {
305 if ($cell->hasAttribute("ColSpan")) {
306 $cell->removeAttribute("ColSpan");
307 }
308 }
309 if ((int) ($a_rowspans[$ckey] ?? 0) > 1) {
310 $cell->setAttribute("RowSpan", (int) $a_rowspans[$ckey]);
311 } else {
312 if ($cell->hasAttribute("RowSpan")) {
313 $cell->removeAttribute("RowSpan");
314 }
315 }
316 }
317 $x++;
318 }
319 $y++;
320 }
321 }
322 $this->fixHideAndSpans();
323 }
324
330 public function fixHideAndSpans(): void
331 {
332 // first: get max x and y
333 $max_x = $max_y = 0;
334 $y = 0;
335 $rows = $this->getChildNode()->childNodes;
336
337 foreach ($rows as $row) {
338 if ($row->nodeName == "TableRow") {
339 $x = 0;
340 $cells = $row->childNodes;
341 foreach ($cells as $cell) {
342 if ($cell->nodeName == "TableData") {
343 $max_x = max($max_x, $x);
344 $max_y = max($max_y, $y);
345 }
346 $x++;
347 }
348 $y++;
349 }
350 }
351
352 // second: fix hidden/colspans for all cells
353 $y = 0;
354 $colspans = [];
355 $rowspans = [];
356 $rows = $this->getChildNode()->childNodes;
357 foreach ($rows as $row) {
358 if ($row->nodeName == "TableRow") {
359 $x = 0;
360 $cells = $row->childNodes;
361 foreach ($cells as $cell) {
362 if ($cell->nodeName == "TableData") {
363 $cspan = max(1, (int) $cell->getAttribute("ColSpan"));
364 $rspan = max(1, (int) $cell->getAttribute("RowSpan"));
365
366 // if col or rowspan is to high: reduce it to the max
367 if ($cspan > $max_x - $x + 1) {
368 $cell->setAttribute("ColSpan", $max_x - $x + 1);
369 $cspan = $max_x - $x + 1;
370 }
371 if ($rspan > $max_y - $y + 1) {
372 $cell->setAttribute("RowSpan", $max_y - $y + 1);
373 $rspan = $max_y - $y + 1;
374 }
375
376 // check hidden status
377 if ($this->checkCellHidden($colspans, $rowspans, $x, $y)) {
378 // hidden: set hidden flag, remove col and rowspan
379 $cell->setAttribute("Hidden", "Y");
380 $cspan = 1;
381 $rspan = 1;
382 if ($cell->hasAttribute("ColSpan")) {
383 $cell->removeAttribute("ColSpan");
384 }
385 if ($cell->hasAttribute("RowSpan")) {
386 $cell->removeAttribute("RowSpan");
387 }
388 $this->makeEmptyCell($cell);
389 } else {
390 // not hidden: remove hidden flag if existing
391 if ($cell->hasAttribute("Hidden")) {
392 $cell->removeAttribute("Hidden");
393 }
394 }
395
396 $colspans[$x][$y] = $cspan;
397 $rowspans[$x][$y] = $rspan;
398 }
399 $x++;
400 }
401 $y++;
402 }
403 }
404 }
405
406
407 public function makeEmptyCell(DomNode $td_node): void
408 {
409 // delete children of paragraph node
410 $this->dom_util->deleteAllChilds($td_node);
411 }
412
416 public function checkCellHidden(array $colspans, array $rowspans, int $x, int $y): bool
417 {
418 for ($i = 0; $i <= $x; $i++) {
419 for ($j = 0; $j <= $y; $j++) {
420 if ($i != $x || $j != $y) {
421 if ((($i + $colspans[$i][$j] > $x) &&
422 ($j + $rowspans[$i][$j] > $y))) {
423 return true;
424 }
425 }
426 }
427 }
428 return false;
429 }
430
434 public function getAllCellClasses(): array
435 {
436 $classes = array();
437 $rows = $this->getChildNode()->childNodes;
438 foreach ($rows as $row) {
439 if ($row->nodeName == "TableRow") {
440 $cells = $row->childNodes;
441 foreach ($cells as $cell) {
442 if ($cell->nodeName == "TableData") {
443 $classes[$cell->getAttribute("HierId") . ":" . $cell->getAttribute("PCID")]
444 = $cell->getAttribute("Class");
445 }
446 }
447 }
448 }
449
450 return $classes;
451 }
452
453 public function getAllCellAlignments(): array
454 {
455 $classes = array();
456 $rows = $this->getChildNode()->childNodes;
457 foreach ($rows as $row) {
458 if ($row->nodeName == "TableRow") {
459 $cells = $row->childNodes;
460 foreach ($cells as $cell) {
461 if ($cell->nodeName == "TableData") {
462 $classes[$cell->getAttribute("HierId") . ":" . $cell->getAttribute("PCID")]
463 = $cell->getAttribute("HorizontalAlign");
464 }
465 }
466 }
467 }
468
469 return $classes;
470 }
471
475 public function getAllCellSpans(): array
476 {
477 $spans = array();
478 $rows = $this->getChildNode()->childNodes;
479 $y = 0;
480 $max_x = 0;
481 $max_y = 0;
482 foreach ($rows as $row) {
483 if ($row->nodeName == "TableRow") {
484 $x = 0;
485 $cells = $row->childNodes;
486 foreach ($cells as $cell) {
487 if ($cell->nodeName == "TableData") {
488 $spans[$cell->getAttribute("HierId") . ":" . $cell->getAttribute("PCID")]
489 = array("x" => $x, "y" => $y, "colspan" => $cell->getAttribute("ColSpan"),
490 "rowspan" => $cell->getAttribute("RowSpan"));
491 $max_x = max($max_x, $x);
492 $max_y = max($max_y, $y);
493 }
494 $x++;
495 }
496 $y++;
497 }
498 }
499 foreach ($spans as $k => $v) {
500 $spans[$k]["max_x"] = $max_x;
501 $spans[$k]["max_y"] = $max_y;
502 }
503
504 return $spans;
505 }
506
511 public function getAllCellWidths(): array
512 {
513 $widths = array();
514 $rows = $this->getChildNode()->childNodes;
515 foreach ($rows as $row) {
516 if ($row->nodeName == "TableRow") {
517 $cells = $row->childNodes;
518 foreach ($cells as $cell) {
519 if ($cell->nodeName == "TableData") {
520 $widths[$cell->getAttribute("HierId") . ":" . $cell->getAttribute("PCID")]
521 = $cell->getAttribute("Width");
522 }
523 }
524 }
525 }
526
527 return $widths;
528 }
529
533 public function setTDClass(
534 string $a_hier_id,
535 string $a_class,
536 string $a_pc_id = ""
537 ): void {
538 if ($a_pc_id == "") {
539 $path = "//TableData[@HierId = '" . $a_hier_id . "']";
540 } else {
541 $path = "//TableData[@PCID = '" . $a_pc_id . "']";
542 }
543 $nodes = $this->dom_util->path($this->dom_doc, $path);
544 if (count($nodes) == 1) {
545 if ($a_class != "") {
546 $nodes->item(0)->setAttribute("Class", $a_class);
547 } else {
548 if ($nodes->item(0)->hasAttribute("Class")) {
549 $nodes->item(0)->removeAttribute("Class");
550 }
551 }
552 }
553 }
554
558 public function setTDAlignment(
559 string $a_hier_id,
560 string $a_class,
561 string $a_pc_id = ""
562 ): void {
563 if ($a_pc_id == "") {
564 $path = "//TableData[@HierId = '" . $a_hier_id . "']";
565 } else {
566 $path = "//TableData[@PCID = '" . $a_pc_id . "']";
567 }
568 $nodes = $this->dom_util->path($this->dom_doc, $path);
569 if (count($nodes) == 1) {
570 if ($a_class != "") {
571 $nodes->item(0)->setAttribute("HorizontalAlign", $a_class);
572 } else {
573 if ($nodes->item(0)->hasAttribute("HorizontalAlign")) {
574 $nodes->item(0)->removeAttribute("HorizontalAlign");
575 }
576 }
577 }
578 }
579
580 public function getCaption(): string
581 {
582 $hier_id = $this->getHierId();
583 if (!empty($hier_id)) {
584 $path = "//PageContent[@HierId = '" . $hier_id . "']/Table/Caption";
585 $nodes = $this->dom_util->path($this->dom_doc, $path);
586 if (count($nodes) == 1) {
587 return $this->dom_util->getContent($nodes->item(0));
588 }
589 }
590 return "";
591 }
592
596 public function getCaptionAlign(): string
597 {
598 $hier_id = $this->getHierId();
599 if (!empty($hier_id)) {
600 $path = "//PageContent[@HierId = '" . $hier_id . "']/Table/Caption";
601 $nodes = $this->dom_util->path($this->dom_doc, $path);
602 if (count($nodes) == 1) {
603 return $nodes->item(0)->getAttribute("Align");
604 }
605 }
606 return "";
607 }
608
609 public function setCaption(string $a_content, string $a_align): void
610 {
611 if ($a_content != "") {
612 $this->dom_util->setFirstOptionalElement(
613 $this->getChildNode(),
614 "Caption",
615 array("Summary", "TableRow"),
616 $a_content,
617 array("Align" => $a_align)
618 );
619 } else {
620 $this->dom_util->deleteAllChildsByName(
621 $this->getChildNode(),
622 array("Caption")
623 );
624 }
625 }
626
627 public function setFirstRowStyle(
628 string $a_class
629 ): void {
630 foreach ($this->getChildNode()->childNodes as $child) {
631 if ($child->nodeName == "TableRow") {
632 foreach ($child->childNodes as $gchild) {
633 if ($gchild->nodeName == "TableData") {
634 $gchild->setAttribute("Class", $a_class);
635 }
636 }
637 return;
638 }
639 }
640 }
641
645 public function setClass(string $a_class): void
646 {
647 $this->setTableAttribute("Class", $a_class);
648 }
649
650 public function getClass(): string
651 {
652 return $this->getTableAttribute("Class");
653 }
654
655 public function setTemplate(string $a_template): void
656 {
657 $this->setTableAttribute("Template", $a_template);
658 }
659
660 public function getTemplate(): string
661 {
662 return $this->getTableAttribute("Template");
663 }
664
665 public function setHeaderRows(int $a_nr): void
666 {
667 $this->setTableAttribute("HeaderRows", $a_nr);
668 }
669
670 public function getHeaderRows(): int
671 {
672 return (int) $this->getTableAttribute("HeaderRows");
673 }
674
675 public function setFooterRows(int $a_nr): void
676 {
677 $this->setTableAttribute("FooterRows", $a_nr);
678 }
679
680 public function getFooterRows(): int
681 {
682 return (int) $this->getTableAttribute("FooterRows");
683 }
684
685 public function setHeaderCols(int $a_nr): void
686 {
687 $this->setTableAttribute("HeaderCols", $a_nr);
688 }
689
690 public function getHeaderCols(): int
691 {
692 return (int) $this->getTableAttribute("HeaderCols");
693 }
694
695 public function setFooterCols(int $a_nr): void
696 {
697 $this->setTableAttribute("FooterCols", $a_nr);
698 }
699
700 public function getFooterCols(): int
701 {
702 return (int) $this->getTableAttribute("FooterCols");
703 }
704
708 protected function setTableAttribute(
709 string $a_attr,
710 string $a_value
711 ): void {
712 if (!empty($a_value)) {
713 $this->getChildNode()->setAttribute($a_attr, $a_value);
714 } else {
715 if ($this->getChildNode()->hasAttribute($a_attr)) {
716 $this->getChildNode()->removeAttribute($a_attr);
717 }
718 }
719 }
720
721 public function getTableAttribute(string $a_attr): string
722 {
723 if (!is_null($this->getChildNode())) {
724 return $this->getChildNode()->getAttribute($a_attr);
725 }
726 return "";
727 }
728
729 public static function getLangVars(): array
730 {
731 return array("ed_insert_dtable", "ed_insert_atable","ed_new_row_after", "ed_new_row_before",
732 "ed_new_col_after", "ed_new_col_before", "ed_delete_col",
733 "ed_delete_row", "ed_edit_data", "ed_row_up", "ed_row_down",
734 "ed_col_left", "ed_col_right");
735 }
736
737
738 public static function handleCopiedContent(
739 DOMDocument $a_domdoc,
740 bool $a_self_ass = true,
741 bool $a_clone_mobs = false,
742 int $new_parent_id = 0,
743 int $obj_copy_id = 0
744 ): void {
745 $xpath = new DOMXPath($a_domdoc);
746 $nodes = $xpath->query("//Table");
747 foreach ($nodes as $node) {
748 $node->removeAttribute("Id");
749 }
750 }
751
752 public function getModel(): ?stdClass
753 {
754 $this->log->debug("Get table model start");
755 $model = new \stdClass();
756
757 $y = 0;
758 foreach ($this->getChildNode()->childNodes as $row) {
759 if ($row->nodeName == "TableRow") {
760 $x = 0;
761 foreach ($row->childNodes as $cell) {
762 if ($cell->nodeName == "TableData") {
764 $this->getCellText($y, $x),
765 true,
766 false
767 );
768 $text = ilPCParagraphGUI::xml2outputJS($text);
769 $model->content[$y][$x] = $text;
770 }
771 $x++;
772 }
773 $y++;
774 }
775 }
776
777 if ($this->getTemplate() != "") {
778 $model->template = $this->getTemplate();
779 $model->characteristic = "";
780 } else {
781 $model->characteristic = $this->getClass();
782 $model->template = "";
783 }
784
785 $model->hasHeaderRows = ($this->getHeaderRows() > 0);
786 $this->log->debug("...end");
787 return $model;
788 }
789}
static xml2outputJS(string $s_text)
Prepare content for js output.
static xml2output(string $a_text, bool $a_wysiwyg=false, bool $a_replace_lists=true, bool $unmask=true)
Converts xml from DB to output in edit textarea.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
importSpreadsheet(string $a_lang, string $a_data)
import from table
setTDAlignment(string $a_hier_id, string $a_class, string $a_pc_id="")
set alignment of table data cell
setTDSpans(array $a_colspans, array $a_rowspans)
setTableAttribute(string $a_attr, string $a_value)
Set attribute of table tag.
setBorder(string $a_border)
setFirstRowStyle(string $a_class)
create(ilPageObject $a_pg_obj, string $a_hier_id, string $a_pc_id="")
setCaption(string $a_content, string $a_align)
addRows(int $a_nr_rows, int $a_nr_cols)
add rows to table
setCellSpacing(string $a_spacing)
getCellText(int $i, int $j)
Get cell text of row $i and cell $j.
makeEmptyCell(DomNode $td_node)
setCellPadding(string $a_padding)
setTemplate(string $a_template)
static getLangVars()
Get lang vars needed for editing.
addCell(DOMNode $aRow, string $a_data="", string $a_lang="")
checkCellHidden(array $colspans, array $rowspans, int $x, int $y)
Check hidden status.
setFooterCols(int $a_nr)
setHeaderCols(int $a_nr)
getModel()
Get model as needed for the front-end editor.
setTDWidth(string $a_hier_id, string $a_width, string $a_pc_id="")
set width of table data cell
setLanguage(string $a_lang)
setWidth(string $a_width)
setHorizontalAlign(string $a_halign)
static handleCopiedContent(DOMDocument $a_domdoc, bool $a_self_ass=true, bool $a_clone_mobs=false, int $new_parent_id=0, int $obj_copy_id=0)
Handle copied content.
getTableAttribute(string $a_attr)
setTDClass(string $a_hier_id, string $a_class, string $a_pc_id="")
set class of table data cell
fixHideAndSpans()
Fix Hide and Spans.
setClass(string $a_class)
Set Style Class of table.
getAllCellClasses()
Get all cell classes.
getAllCellSpans()
Get all cell spans.
init()
Init object.
getCellNode(int $i, int $j, bool $create_if_not_exists=false)
Get cell paragraph node of row $i and cell $j.
getCaptionAlign()
get caption alignment (Top | Bottom)
setFooterRows(int $a_nr)
getAllCellWidths()
Get all cell widths.
getTableDataNode(int $i, int $j)
Get cell paragraph node of row $i and cell $j.
setHeaderRows(int $a_nr)
Content object of ilPageObject (see ILIAS DTD).
createInitialChildNode(string $hier_id, string $pc_id, string $child, array $child_attributes=[])
setType(string $a_type)
Set Type.
Class ilPageObject Handles PageObjects of ILIAS Learning Modules (see ILIAS DTD)
$c
Definition: deliver.php:25
$path
Definition: ltiservices.php:30
if(!file_exists('../ilias.ini.php'))
getLanguage()