Ferreteria/v0.6/clade/Sys/Data/Things/Array/View/Grid
Jump to navigation
Jump to search
| ||||||||||||||||||||||||||
About
- PURPOSE: generic Viewer for an Array of Arrays of values (Cells)
- Array-Grid podlings can inherit from this for specialized rendering
History
- 2025-01-14 started
- 2025-11-11 not fully functional yet; changes:
- re-parented from Debug ⇒ View
- in rendering-function list (in
RenderToTable()), changed 'FormatValue' ⇒ 'FormatRow' to reduce confusion
Code
as of 2025-11-11 (not fully functional)
interface iGrid extends BaseIface {
static function FromGridData(GridDataIface $oa) : self;
function RenderAsTable() : string; // implements Render()
function HeadersArray() : array; // rendered headers, as array of content-strings
}
class cGrid extends BaseClass implements iGrid {
// ++ SETUP ++ //
public static function FromGridData(GridDataIface $oa) : iGrid { // was FromArray() -- did this ever get called? 2025-02-02
$oThis = new static($oa);
$oThis->WithArray($oa);
return $oThis;
}
// ++ SETUP: dynamic ++ //
private $oa;
protected function WithArray(GridDataIface $oa) : void { $this->oa = $oa; }
protected function OArray() : GridDataIface { return $this->oa; }
// -- SETUP -- //
// ++ OUTPUT ++ //
protected function FormatValue(mixed $v) : string { return self::PromptForMethod(); }
public function Render() : string { return $this->LayoutAsRows(); }
public function RenderAsTable() : string { return $this->LayoutAsRows(); }
protected function LayoutAsRows(TableIface $oTable=NULL) : string {
if (is_null($oTable)) {
$oTable = static::Screen()->NewTable();
}
$this->RenderToTable($oTable);
return $oTable->Render();
}
protected function RenderToTable(TableIface $oTable) : void {
$oScrn = self::Screen();
$arAll = $this->OArray()->GetVals();
$nRows = count($arAll);
#$this->AmHere("ROWS: [$nRows]");
if ($nRows > 0) {
// get header strings, and add them to output table:
$arHdr = $this->HeadersArray();
if (count($arHdr) > 0) {
$oRow = $oTable->NewRow();
$oRow->IsHeader(TRUE);
$oRow->WithData($arHdr);
}
// iterate through rows:
foreach ($arAll as $kRow => $vRow) {
// $v could (should) be either a Row-type array-object or an array
$okType = FALSE;
#$this->AmHere("vRow is: ".get_class($vRow));
if (is_subclass_of($vRow,RowDataIface::class)) {
$okType = TRUE;
#$this->AmHere(' - MATCHES');
$oRow = $vRow->Inspect()->ValuesRow($oTable);
} elseif(is_array($vRow)) {
$okType = TRUE;
#$this->AmHere(' - is array');
$oRow = $oTable->NewRow();
foreach ($arShow as $ndx => $vCell) {
if (is_a($vCell,CellViewIface::class)) {
$ftCell = $vCell->Render();
} elseif(is_scalar($vCell)) {
$ftCell = $vCell;
} else {
$sType = $this->FormatValue($vCell);
self::ThrowHissy("Unexpected cell element '$sType' in Row.");
}
$oRow->NewCell_frVal($ftCell);
}
$oRow->SetStore($vRow);
} elseif(is_object($vRow) ) {
$okType = TRUE;
$this->AmHereShort('$vRow is '.get_class($vRow));
if (is_a($vRow,RowViewIface::class)) {
$this->AmHere('MATCHES');
$okType = TRUE;
$arFx = ['ValuesRow','FormatRow']; // fx to try
// check possible rendering fx:
foreach ($arFx as $sf) {
if (method_exists($vRow,$sf)) {
$ftVal = $this->$sf($vRow);
// 2025-08-12 IN PROGRESS
$this->AmHere("TO BE WRITTEN (ftVal=[$ftVal])");
throw new \exception('How do we get here?');
break;
}
}
} else {
$this->AmHere(get_class($vRow).' is not a '.RowViewIface::class);
}
}
if (!$okType) {
$sf = 'FormatValue';
#if (method_exists($this,$sf)) {
# $sType = $this->FormatValue($vRow);
if (method_exists($vRow,$sf)) {
$sType = $vRow->FormatValue($vRow);
if (is_object($vRow)) {
echo $vRow->ReflectThis()->Report();
}
$sc = RowViewIface::class;
self::ThrowHissy("Unexpected row element '$sType' in Grid - needs to be array or $sc.");
} else {
#$this->AmHere('What is supposed to happen here?');
$ftVal = TypeFx::DumpLine($vRow);
$oRow = $oTable->NewRow();
$oRow->NewCell_frVal($ftVal);
#echo $vRow->Inspect()->ReflectThis()->Report(); die();
}
}
}
} else {
$oTable->NewRow()->NewCell_frVal($oScrn->ErrorIt('Array is empty.'));
}
}
/**
* ACTION: By default, gets the first array-item and calls its HeadersArray() if available.
* HISTORY:
* 2025-06-21 I'm no longer understanding why $vElem0 needs to implement $siRowView, so commenting that out for now.
*/
public function HeadersArray() : array {
$vElem0 = $this->OArray()->GetFirst();
if (is_object($vElem0)) {
$siRowView = RowViewIface::class;
// 2025-06-22 just require the needed method
$sc = get_class($vElem0);
$sf = __FUNCTION__;
if (method_exists($vElem0,$sf)) {
$arOut = $vElem0->HeadersArray();
} else {
die(self::CodingPrompt("$sf() needs to be implemented by row-element class ($sc) or podling of this grid-class."));
}
/* 2025-06-21 iface requirement
if (is_subclass_of($vElem0,$siRowView)) {
$arOut = $vElem0->HeadersArray();
} else {
$sc = get_class($vElem0);
$sf = __FUNCTION__;
if (method_exists($vElem0,$sf)) {
die(self::CodingPrompt("The row-class ($sc) implements $sf() but not the needed $siRowView interface."));
} else {
die(self::CodingPrompt("$sf() needs to be implemented by row-element class ($sc) or podling of this grid-class."));
}
}
*/
} else {
$sType = gettype($vElem0);
die(self::CodingPrompt("Podling grid-class needs to implement $sf(), because the element can't (it's type '$sType')."));
}
return $arOut;
}
// -- OUTPUT -- //
}
Removed
2025-02-07
from RenderToTable(), removed on 2025-01-10:
// 2025-01-10 replaced by ValueStringsArray();
$oRow->NewCell('#'); // ...though this and the next line...
$oRow->NewCell('filespec'); // ...really didn't belong here *ever*.
foreach ($arAll as $sKey => $v) {
$sVal = $this->FormatValue($v);
$oRow = $oTable->NewRow();
$oRow->NewCell($sKey);
$oRow->NewCell($sVal);
}