["?content", null, "Contenu à afficher pour chaque ligne avant le tableau s'il y a des lignes à afficher"], "after_row" => ["?content", null, "Contenu à afficher pour chaque ligne après le tableau s'il y a des lignes à afficher"], ]; /** @var array|string */ protected $ppBeforeRow; /** @var array|string */ protected $ppAfterRow; function print(): void { try { $this->_rewindRows(); $this->rowIndex = 0; $haveRows = false; while ($this->_validRow()) { $this->origRow = $this->nextRow(); try { if ($this->origRow === null) continue; $skipRow = false; if (!$haveRows) $skipRow = $this->resolveColsHeaders($this->origRow); if (!$skipRow) { $this->row = $this->cookRow($this->origRow); if (!$haveRows) { $haveRows = true; vo::print($this->beforeTable()); vo::stable(["class" => "table", $this->table()]); vo::stbody($this->tbody()); } $this->printBeforeRow(); $this->printRow($this->row); $this->printAfterRow(); $this->rowIndex++; } } finally { $this->_nextRow(); } } if ($haveRows) { vo::etbody(); vo::etable(); vo::print($this->afterTable()); } else { vo::print($this->noData()); } } catch (Exception $e) { $onException = $this->ppOnException; if ($onException !== null) func::call($onException, $e); else throw $e; } } function tr(bool $rowContent): ?iterable { return null; } /** contenu à afficher avant le tableau s'il y a des lignes à afficher */ function beforeRow(): ?iterable { return $this->ppBeforeRow; } function printBeforeRow(): void { $beforeRowContents = $this->beforeRow(); if ($beforeRowContents !== null) { vo::tr([ $this->tr(false), v::td([ "colspan" => 2, $beforeRowContents, ]), ]); } } /** contenu à afficher après le tableau s'il y a des lignes à afficher */ function afterRow(): ?iterable { return $this->ppAfterRow; } function printAfterRow(): void { $afterRowContents = $this->afterRow(); if ($afterRowContents !== null) { vo::tr([ $this->tr(false), v::td([ "colspan" => 2, $afterRowContents, ]), ]); } } function printRow(array $row): void { $this->index = 0; $headers = $this->headers; $headerCol = 0; $headerIndex = 0; foreach ($this->cols as $this->col) { vo::str($this->tr(true)); if ($headerCol == $this->index) { if ($headerCol == 0) iter::rewind($headers); else iter::next($headers); if (iter::valid($headers)) { $header = iter::current($headers, $key); $label = $header["label"]; if ($label === null) $label = $header["name"]; $rowspan = $header["span"]; if ($key === $headerIndex) { $headerIndex++; $headerCol++; } else { $headerCol += $rowspan; } vo::print($this->colTh($label, $rowspan)); } } $value = $this->col !== null? $row[$this->col]: null; vo::print($this->colTd($value)); vo::etr(); $this->index++; } } function colTh($header, ?int $rowspan): array { return v::th([ "rowspan" => $rowspan, $header, ]); } }