1ea5ad12aSMichael Grosse<?php 2ea5ad12aSMichael Grosse 3ea5ad12aSMichael Grossenamespace dokuwiki\plugin\struct\meta; 4ea5ad12aSMichael Grosse 5ea5ad12aSMichael Grosse/** 6ea5ad12aSMichael Grosse * Class AggregationList 7ea5ad12aSMichael Grosse * 8ea5ad12aSMichael Grosse * @package dokuwiki\plugin\struct\meta 9ea5ad12aSMichael Grosse */ 10d90aa848SAndreas Gohrclass AggregationList extends Aggregation 11d6d97f60SAnna Dabrowska{ 12d90aa848SAndreas Gohr /** @var int number of all results */ 13ea5ad12aSMichael Grosse protected $resultColumnCount; 14ea5ad12aSMichael Grosse 15d90aa848SAndreas Gohr /** @inheritdoc */ 16d6d97f60SAnna Dabrowska public function __construct($id, $mode, \Doku_Renderer $renderer, SearchConfig $searchConfig) 17d6d97f60SAnna Dabrowska { 18d90aa848SAndreas Gohr parent::__construct($id, $mode, $renderer, $searchConfig); 19ea5ad12aSMichael Grosse $this->resultColumnCount = count($this->columns); 20ea5ad12aSMichael Grosse } 21ea5ad12aSMichael Grosse 22d90aa848SAndreas Gohr /** @inheritdoc */ 23d90aa848SAndreas Gohr public function render($showNotFound = false) 24d6d97f60SAnna Dabrowska { 25d90aa848SAndreas Gohr if ($this->result) { 265bc00e11SAndreas Gohr $nestedResult = new NestedResult($this->result); 27ce44c639SAndreas Gohr $root = $nestedResult->getRoot($this->data['nesting'], $this->data['index']); 285bc00e11SAndreas Gohr $this->renderNode($root); 29d90aa848SAndreas Gohr } elseif ($showNotFound) { 30d90aa848SAndreas Gohr $this->renderer->cdata($this->helper->getLang('none')); 31d90aa848SAndreas Gohr } 325bc00e11SAndreas Gohr } 33ea5ad12aSMichael Grosse 345bc00e11SAndreas Gohr /** 355bc00e11SAndreas Gohr * Recursively render the result tree 365bc00e11SAndreas Gohr * 375bc00e11SAndreas Gohr * @param NestedValue $node 385bc00e11SAndreas Gohr * @return void 395bc00e11SAndreas Gohr */ 405bc00e11SAndreas Gohr protected function renderNode(NestedValue $node) 415bc00e11SAndreas Gohr { 425bc00e11SAndreas Gohr $self = $node->getValueObject(); // null for root node 437234bfb1Ssplitbrain $children = $node->getChildren(!$self instanceof Value && $this->data['index']); // sort only for index 445bc00e11SAndreas Gohr $results = $node->getResultRows(); 455bc00e11SAndreas Gohr 465bc00e11SAndreas Gohr // all our content is in a listitem, unless we are the root node 477234bfb1Ssplitbrain if ($self instanceof Value) { 485bc00e11SAndreas Gohr $this->renderer->listitem_open($node->getDepth() + 1); // levels are 1 based 495bc00e11SAndreas Gohr } 505bc00e11SAndreas Gohr 515bc00e11SAndreas Gohr // render own value if available 527234bfb1Ssplitbrain if ($self instanceof Value) { 535bc00e11SAndreas Gohr $this->renderer->listcontent_open(); 547b7a9290SAndreas Gohr $this->renderListItem([$self], $node->getDepth(), true); // zero based depth 555bc00e11SAndreas Gohr $this->renderer->listcontent_close(); 565bc00e11SAndreas Gohr } 575bc00e11SAndreas Gohr 585bc00e11SAndreas Gohr // render children or results as sub-list 595bc00e11SAndreas Gohr if ($children || $results) { 602c6e107cSMichael Grosse $this->renderer->listu_open(); 61ea5ad12aSMichael Grosse 625bc00e11SAndreas Gohr foreach ($children as $child) { 635bc00e11SAndreas Gohr $this->renderNode($child); 645bc00e11SAndreas Gohr } 655bc00e11SAndreas Gohr 665bc00e11SAndreas Gohr foreach ($results as $result) { 675bc00e11SAndreas Gohr $this->renderer->listitem_open($node->getDepth() + 2); // levels are 1 based, this is one deeper 682c6e107cSMichael Grosse $this->renderer->listcontent_open(); 695bc00e11SAndreas Gohr $this->renderListItem($result, $node->getDepth() + 1); // zero based depth, one deeper 702c6e107cSMichael Grosse $this->renderer->listcontent_close(); 712c6e107cSMichael Grosse $this->renderer->listitem_close(); 72ea5ad12aSMichael Grosse } 73ea5ad12aSMichael Grosse 742c6e107cSMichael Grosse $this->renderer->listu_close(); 755bc00e11SAndreas Gohr } 76ea5ad12aSMichael Grosse 775bc00e11SAndreas Gohr // close listitem if opened 787234bfb1Ssplitbrain if ($self instanceof Value) { 795bc00e11SAndreas Gohr $this->renderer->listitem_close(); 805bc00e11SAndreas Gohr } 81ea5ad12aSMichael Grosse } 82ea5ad12aSMichael Grosse 83ea5ad12aSMichael Grosse /** 845bc00e11SAndreas Gohr * Render the content of a single list item 855bc00e11SAndreas Gohr * 865bc00e11SAndreas Gohr * @param Value[] $resultrow 875bc00e11SAndreas Gohr * @param int $depth The current nesting depth (zero based) 887b7a9290SAndreas Gohr * @param bool $showEmpty show a placeholder for empty values? 89ea5ad12aSMichael Grosse */ 907b7a9290SAndreas Gohr protected function renderListItem($resultrow, $depth, $showEmpty = false) 91d6d97f60SAnna Dabrowska { 92*62c804ccSAnna Dabrowska $config = $this->searchConfig->getConf(); 93*62c804ccSAnna Dabrowska $sepbyheaders = $config['sepbyheaders']; 94*62c804ccSAnna Dabrowska $headers = $config['headers']; 95ea5ad12aSMichael Grosse 965bc00e11SAndreas Gohr foreach ($resultrow as $index => $value) { 97*62c804ccSAnna Dabrowska // when nesting, the resultrow is shifted by the nesting depth 98*62c804ccSAnna Dabrowska $column = $index; 99*62c804ccSAnna Dabrowska if ($config['nesting']) { 100*62c804ccSAnna Dabrowska $column += $depth; 101*62c804ccSAnna Dabrowska } 102ea5ad12aSMichael Grosse if ($sepbyheaders && !empty($headers[$column])) { 1035bc00e11SAndreas Gohr $header = $headers[$column]; 1042c6e107cSMichael Grosse } else { 1055bc00e11SAndreas Gohr $header = ''; 1065bc00e11SAndreas Gohr } 1075bc00e11SAndreas Gohr 1085bc00e11SAndreas Gohr if ($this->mode === 'xhtml') { 1097b7a9290SAndreas Gohr $this->renderValueXHTML($value, $header, $showEmpty); 1105bc00e11SAndreas Gohr } else { 1117b7a9290SAndreas Gohr $this->renderValueGeneric($value, $header, $showEmpty); 112ea5ad12aSMichael Grosse } 1132c6e107cSMichael Grosse } 1142c6e107cSMichael Grosse } 1155bc00e11SAndreas Gohr 1165bc00e11SAndreas Gohr /** 1175bc00e11SAndreas Gohr * Render the given Value in a XHTML renderer 1185bc00e11SAndreas Gohr * @param Value $value 1195bc00e11SAndreas Gohr * @param string $header 1207b7a9290SAndreas Gohr * @param bool $showEmpty 1215bc00e11SAndreas Gohr * @return void 1225bc00e11SAndreas Gohr */ 1237b7a9290SAndreas Gohr protected function renderValueXHTML($value, $header, $showEmpty = false) 1245bc00e11SAndreas Gohr { 1255bc00e11SAndreas Gohr $attributes = [ 1265bc00e11SAndreas Gohr 'data-struct-column' => strtolower($value->getColumn()->getFullQualifiedLabel()), 1275bc00e11SAndreas Gohr 'data-struct-type' => strtolower($value->getColumn()->getType()->getClass()), 1285bc00e11SAndreas Gohr 'class' => 'li', // default dokuwiki content wrapper 1295bc00e11SAndreas Gohr ]; 1305bc00e11SAndreas Gohr 1315bc00e11SAndreas Gohr $this->renderer->doc .= sprintf('<div %s>', buildAttributes($attributes)); // wrapper 1325bc00e11SAndreas Gohr if ($header !== '') { 1335bc00e11SAndreas Gohr $this->renderer->doc .= sprintf('<span class="struct_header">%s</span> ', hsc($header)); 1345bc00e11SAndreas Gohr } 1355bc00e11SAndreas Gohr $this->renderer->doc .= '<div class="struct_value">'; 1367b7a9290SAndreas Gohr if ($value->isEmpty() && $showEmpty) { 1377b7a9290SAndreas Gohr $this->renderer->doc .= '<span class="struct_na">' . $this->helper->getLang('na') . '</span>'; 1387b7a9290SAndreas Gohr } else { 139ea5ad12aSMichael Grosse $value->render($this->renderer, $this->mode); 1407b7a9290SAndreas Gohr } 141ea5ad12aSMichael Grosse $this->renderer->doc .= '</div>'; 1425bc00e11SAndreas Gohr $this->renderer->doc .= '</div> '; // wrapper 143ea5ad12aSMichael Grosse } 1445bc00e11SAndreas Gohr 1455bc00e11SAndreas Gohr /** 1465bc00e11SAndreas Gohr * Render the given Value in any non-XHTML renderer 1475bc00e11SAndreas Gohr * @param Value $value 1485bc00e11SAndreas Gohr * @param string $header 1495bc00e11SAndreas Gohr * @return void 1505bc00e11SAndreas Gohr */ 1517b7a9290SAndreas Gohr protected function renderValueGeneric($value, $header, $showEmpty = false) 1525bc00e11SAndreas Gohr { 1535bc00e11SAndreas Gohr $this->renderer->listcontent_open(); 1545bc00e11SAndreas Gohr if ($header !== '') $this->renderer->cdata($header . ' '); 1557b7a9290SAndreas Gohr if ($value->isEmpty() && $showEmpty) { 1567b7a9290SAndreas Gohr $this->renderer->cdata($this->helper->getLang('na')); 1577b7a9290SAndreas Gohr } else { 1585bc00e11SAndreas Gohr $value->render($this->renderer, $this->mode); 1597b7a9290SAndreas Gohr } 1605bc00e11SAndreas Gohr $this->renderer->listcontent_close(); 161ea5ad12aSMichael Grosse } 162ea5ad12aSMichael Grosse} 163