154 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			154 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| namespace nur\v\bs3\vc;
 | |
| 
 | |
| use Exception;
 | |
| use nur\b\params\Tparametrable;
 | |
| use nur\func;
 | |
| use nur\iter;
 | |
| use nur\v\v;
 | |
| use nur\v\vo;
 | |
| 
 | |
| /**
 | |
|  * Class CVerticalTable: comme {@link CTable} mais les données sont affichées
 | |
|  * de façon verticale
 | |
|  */
 | |
| class CVerticalTable extends CTable {
 | |
|   use Tparametrable;
 | |
| 
 | |
|   const TABLE_CLASS = "table-bordered table-auto";
 | |
| 
 | |
|   const PARAMETRABLE_PARAMS_SCHEMA = [
 | |
|     "before_row" => ["?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->rawRow = $this->_currentRow($this->rowKey);
 | |
|         try {
 | |
|           $this->origRow = $this->nextRow();
 | |
|           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,
 | |
|     ]);
 | |
|   }
 | |
| }
 |