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{ 12ea5ad12aSMichael Grosse 13d90aa848SAndreas Gohr /** @var int number of all results */ 14ea5ad12aSMichael Grosse protected $resultColumnCount; 15ea5ad12aSMichael Grosse 16d90aa848SAndreas Gohr /** @inheritdoc */ 17d6d97f60SAnna Dabrowska public function __construct($id, $mode, \Doku_Renderer $renderer, SearchConfig $searchConfig) 18d6d97f60SAnna Dabrowska { 19d90aa848SAndreas Gohr parent::__construct($id, $mode, $renderer, $searchConfig); 20ea5ad12aSMichael Grosse $this->resultColumnCount = count($this->columns); 21ea5ad12aSMichael Grosse } 22ea5ad12aSMichael Grosse 23d90aa848SAndreas Gohr /** @inheritdoc */ 24d90aa848SAndreas Gohr public function render($showNotFound = false) 25d6d97f60SAnna Dabrowska { 26d90aa848SAndreas Gohr $this->startScope(); 27d90aa848SAndreas Gohr if ($this->result) { 285bc00e11SAndreas Gohr $nestedResult = new NestedResult($this->result); 29*ce44c639SAndreas Gohr $root = $nestedResult->getRoot($this->data['nesting'], $this->data['index']); 305bc00e11SAndreas Gohr $this->renderNode($root); 31d90aa848SAndreas Gohr } elseif ($showNotFound) { 32d90aa848SAndreas Gohr $this->renderer->cdata($this->helper->getLang('none')); 33d90aa848SAndreas Gohr } 345bc00e11SAndreas Gohr $this->finishScope(); 355bc00e11SAndreas Gohr } 36ea5ad12aSMichael Grosse 375bc00e11SAndreas Gohr /** 385bc00e11SAndreas Gohr * Recursively render the result tree 395bc00e11SAndreas Gohr * 405bc00e11SAndreas Gohr * @param NestedValue $node 415bc00e11SAndreas Gohr * @return void 425bc00e11SAndreas Gohr */ 435bc00e11SAndreas Gohr protected function renderNode(NestedValue $node) 445bc00e11SAndreas Gohr { 455bc00e11SAndreas Gohr $self = $node->getValueObject(); // null for root node 465bc00e11SAndreas Gohr $children = $node->getChildren(); 475bc00e11SAndreas Gohr $results = $node->getResultRows(); 485bc00e11SAndreas Gohr 495bc00e11SAndreas Gohr // all our content is in a listitem, unless we are the root node 505bc00e11SAndreas Gohr if ($self) { 515bc00e11SAndreas Gohr $this->renderer->listitem_open($node->getDepth() + 1); // levels are 1 based 525bc00e11SAndreas Gohr } 535bc00e11SAndreas Gohr 545bc00e11SAndreas Gohr // render own value if available 555bc00e11SAndreas Gohr if ($self) { 565bc00e11SAndreas Gohr $this->renderer->listcontent_open(); 575bc00e11SAndreas Gohr $this->renderListItem([$self], $node->getDepth()); // zero based depth 585bc00e11SAndreas Gohr $this->renderer->listcontent_close(); 595bc00e11SAndreas Gohr } 605bc00e11SAndreas Gohr 615bc00e11SAndreas Gohr // render children or results as sub-list 625bc00e11SAndreas Gohr if ($children || $results) { 632c6e107cSMichael Grosse $this->renderer->listu_open(); 64ea5ad12aSMichael Grosse 655bc00e11SAndreas Gohr foreach ($children as $child) { 665bc00e11SAndreas Gohr $this->renderNode($child); 675bc00e11SAndreas Gohr } 685bc00e11SAndreas Gohr 695bc00e11SAndreas Gohr foreach ($results as $result) { 705bc00e11SAndreas Gohr $this->renderer->listitem_open($node->getDepth() + 2); // levels are 1 based, this is one deeper 712c6e107cSMichael Grosse $this->renderer->listcontent_open(); 725bc00e11SAndreas Gohr $this->renderListItem($result, $node->getDepth() + 1); // zero based depth, one deeper 732c6e107cSMichael Grosse $this->renderer->listcontent_close(); 742c6e107cSMichael Grosse $this->renderer->listitem_close(); 75ea5ad12aSMichael Grosse } 76ea5ad12aSMichael Grosse 772c6e107cSMichael Grosse $this->renderer->listu_close(); 785bc00e11SAndreas Gohr } 79ea5ad12aSMichael Grosse 805bc00e11SAndreas Gohr // close listitem if opened 815bc00e11SAndreas Gohr if ($self) { 825bc00e11SAndreas Gohr $this->renderer->listitem_close(); 835bc00e11SAndreas Gohr } 84ea5ad12aSMichael Grosse } 85ea5ad12aSMichael Grosse 86ea5ad12aSMichael Grosse /** 87ea5ad12aSMichael Grosse * Adds additional info to document and renderer in XHTML mode 88ea5ad12aSMichael Grosse * 89ea5ad12aSMichael Grosse * @see finishScope() 90ea5ad12aSMichael Grosse */ 91d6d97f60SAnna Dabrowska protected function startScope() 92d6d97f60SAnna Dabrowska { 93ea5ad12aSMichael Grosse // wrapping div 94ea5ad12aSMichael Grosse if ($this->mode != 'xhtml') return; 95ea5ad12aSMichael Grosse $this->renderer->doc .= "<div class=\"structaggregation listaggregation\">"; 96ea5ad12aSMichael Grosse } 97ea5ad12aSMichael Grosse 98ea5ad12aSMichael Grosse /** 99ea5ad12aSMichael Grosse * Closes anything opened in startScope() 100ea5ad12aSMichael Grosse * 101ea5ad12aSMichael Grosse * @see startScope() 102ea5ad12aSMichael Grosse */ 103d6d97f60SAnna Dabrowska protected function finishScope() 104d6d97f60SAnna Dabrowska { 105ea5ad12aSMichael Grosse // wrapping div 106ea5ad12aSMichael Grosse if ($this->mode != 'xhtml') return; 107ea5ad12aSMichael Grosse $this->renderer->doc .= '</div>'; 108ea5ad12aSMichael Grosse } 109ea5ad12aSMichael Grosse 1105bc00e11SAndreas Gohr 111ea5ad12aSMichael Grosse /** 1125bc00e11SAndreas Gohr * Render the content of a single list item 1135bc00e11SAndreas Gohr * 1145bc00e11SAndreas Gohr * @param Value[] $resultrow 1155bc00e11SAndreas Gohr * @param int $depth The current nesting depth (zero based) 116ea5ad12aSMichael Grosse */ 1175bc00e11SAndreas Gohr protected function renderListItem($resultrow, $depth) 118d6d97f60SAnna Dabrowska { 119ea5ad12aSMichael Grosse $sepbyheaders = $this->searchConfig->getConf()['sepbyheaders']; 120ea5ad12aSMichael Grosse $headers = $this->searchConfig->getConf()['headers']; 121ea5ad12aSMichael Grosse 1225bc00e11SAndreas Gohr foreach ($resultrow as $index => $value) { 1235bc00e11SAndreas Gohr if ($value->isEmpty()) continue; 1245bc00e11SAndreas Gohr $column = $index + $depth; // the resultrow is shifted by the nesting depth 125ea5ad12aSMichael Grosse if ($sepbyheaders && !empty($headers[$column])) { 1265bc00e11SAndreas Gohr $header = $headers[$column]; 1272c6e107cSMichael Grosse } else { 1285bc00e11SAndreas Gohr $header = ''; 1295bc00e11SAndreas Gohr } 1305bc00e11SAndreas Gohr 1315bc00e11SAndreas Gohr if ($this->mode === 'xhtml') { 1325bc00e11SAndreas Gohr $this->renderValueXHTML($value, $header); 1335bc00e11SAndreas Gohr } else { 1345bc00e11SAndreas Gohr $this->renderValueGeneric($value, $header); 135ea5ad12aSMichael Grosse } 1362c6e107cSMichael Grosse } 1372c6e107cSMichael Grosse } 1385bc00e11SAndreas Gohr 1395bc00e11SAndreas Gohr /** 1405bc00e11SAndreas Gohr * Render the given Value in a XHTML renderer 1415bc00e11SAndreas Gohr * @param Value $value 1425bc00e11SAndreas Gohr * @param string $header 1435bc00e11SAndreas Gohr * @return void 1445bc00e11SAndreas Gohr */ 1455bc00e11SAndreas Gohr protected function renderValueXHTML($value, $header) 1465bc00e11SAndreas Gohr { 1475bc00e11SAndreas Gohr $attributes = [ 1485bc00e11SAndreas Gohr 'data-struct-column' => strtolower($value->getColumn()->getFullQualifiedLabel()), 1495bc00e11SAndreas Gohr 'data-struct-type' => strtolower($value->getColumn()->getType()->getClass()), 1505bc00e11SAndreas Gohr 'class' => 'li', // default dokuwiki content wrapper 1515bc00e11SAndreas Gohr ]; 1525bc00e11SAndreas Gohr 1535bc00e11SAndreas Gohr $this->renderer->doc .= sprintf('<div %s>', buildAttributes($attributes)); // wrapper 1545bc00e11SAndreas Gohr if ($header !== '') { 1555bc00e11SAndreas Gohr $this->renderer->doc .= sprintf('<span class="struct_header">%s</span> ', hsc($header)); 1565bc00e11SAndreas Gohr } 1575bc00e11SAndreas Gohr $this->renderer->doc .= '<div class="struct_value">'; 158ea5ad12aSMichael Grosse $value->render($this->renderer, $this->mode); 159ea5ad12aSMichael Grosse $this->renderer->doc .= '</div>'; 1605bc00e11SAndreas Gohr $this->renderer->doc .= '</div> '; // wrapper 161ea5ad12aSMichael Grosse } 1625bc00e11SAndreas Gohr 1635bc00e11SAndreas Gohr /** 1645bc00e11SAndreas Gohr * Render the given Value in any non-XHTML renderer 1655bc00e11SAndreas Gohr * @param Value $value 1665bc00e11SAndreas Gohr * @param string $header 1675bc00e11SAndreas Gohr * @return void 1685bc00e11SAndreas Gohr */ 1695bc00e11SAndreas Gohr protected function renderValueGeneric($value, $header) 1705bc00e11SAndreas Gohr { 1715bc00e11SAndreas Gohr $this->renderer->listcontent_open(); 1725bc00e11SAndreas Gohr if ($header !== '') $this->renderer->cdata($header . ' '); 1735bc00e11SAndreas Gohr $value->render($this->renderer, $this->mode); 1745bc00e11SAndreas Gohr $this->renderer->listcontent_close(); 175ea5ad12aSMichael Grosse } 176ea5ad12aSMichael Grosse} 177