resultColumnCount = count($this->columns); } /** @inheritdoc */ public function render($showNotFound = false) { if ($this->searchConfig->getResult()) { $nestedResult = new NestedResult($this->searchConfig->getRows()); $root = $nestedResult->getRoot($this->data['nesting'], $this->data['index']); $this->renderNode($root); } elseif ($showNotFound) { $this->renderer->cdata($this->helper->getLang('none')); } } /** * Recursively render the result tree * * @param NestedValue $node * @return void */ protected function renderNode(NestedValue $node) { $self = $node->getValueObject(); // null for root node $children = $node->getChildren(!$self instanceof Value && $this->data['index']); // sort only for index $results = $node->getResultRows(); // all our content is in a listitem, unless we are the root node if ($self instanceof Value) { $this->renderer->listitem_open($node->getDepth() + 1); // levels are 1 based } // render own value if available if ($self instanceof Value) { $this->renderer->listcontent_open(); $this->renderListItem([$self], $node->getDepth(), true); // zero based depth $this->renderer->listcontent_close(); } // render children or results as sub-list if ($children || $results) { $this->renderer->listu_open(); foreach ($children as $child) { $this->renderNode($child); } foreach ($results as $result) { $this->renderer->listitem_open($node->getDepth() + 2); // levels are 1 based, this is one deeper $this->renderer->listcontent_open(); $this->renderListItem($result, $node->getDepth() + 1); // zero based depth, one deeper $this->renderer->listcontent_close(); $this->renderer->listitem_close(); } $this->renderer->listu_close(); } // close listitem if opened if ($self instanceof Value) { $this->renderer->listitem_close(); } } /** * Render the content of a single list item * * @param Value[] $resultrow * @param int $depth The current nesting depth (zero based) * @param bool $showEmpty show a placeholder for empty values? */ protected function renderListItem($resultrow, $depth, $showEmpty = false) { $config = $this->searchConfig->getConf(); $sepbyheaders = $config['sepbyheaders']; $headers = $config['headers']; foreach ($resultrow as $index => $value) { // when nesting, the resultrow is shifted by the nesting depth $column = $index; if ($config['nesting']) { $column += $depth; } if ($sepbyheaders && !empty($headers[$column])) { $header = $headers[$column]; } else { $header = ''; } if ($this->mode === 'xhtml') { $this->renderValueXHTML($value, $header, $showEmpty); } else { $this->renderValueGeneric($value, $header, $showEmpty); } } } /** * Render the given Value in a XHTML renderer * @param Value $value * @param string $header * @param bool $showEmpty * @return void */ protected function renderValueXHTML($value, $header, $showEmpty = false) { $attributes = [ 'data-struct-column' => strtolower($value->getColumn()->getFullQualifiedLabel()), 'data-struct-type' => strtolower($value->getColumn()->getType()->getClass()), 'class' => 'li', // default dokuwiki content wrapper ]; $this->renderer->doc .= sprintf('
', buildAttributes($attributes)); // wrapper if ($header !== '') { $this->renderer->doc .= sprintf('%s ', hsc($header)); } $this->renderer->doc .= '
'; if ($value->isEmpty() && $showEmpty) { $this->renderer->doc .= '' . $this->helper->getLang('na') . ''; } else { $value->render($this->renderer, $this->mode); } $this->renderer->doc .= '
'; $this->renderer->doc .= '
'; // wrapper } /** * Render the given Value in any non-XHTML renderer * @param Value $value * @param string $header * @return void */ protected function renderValueGeneric($value, $header, $showEmpty = false) { $this->renderer->listcontent_open(); if ($header !== '') $this->renderer->cdata($header . ' '); if ($value->isEmpty() && $showEmpty) { $this->renderer->cdata($this->helper->getLang('na')); } else { $value->render($this->renderer, $this->mode); } $this->renderer->listcontent_close(); } }