xref: /plugin/struct/meta/AggregationList.php (revision 7b7a9290f8a0cb5d24bd768166706412896cffe5)
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
435bc00e11SAndreas Gohr        $children = $node->getChildren();
445bc00e11SAndreas Gohr        $results = $node->getResultRows();
455bc00e11SAndreas Gohr
465bc00e11SAndreas Gohr        // all our content is in a listitem, unless we are the root node
475bc00e11SAndreas Gohr        if ($self) {
485bc00e11SAndreas Gohr            $this->renderer->listitem_open($node->getDepth() + 1); // levels are 1 based
495bc00e11SAndreas Gohr        }
505bc00e11SAndreas Gohr
515bc00e11SAndreas Gohr        // render own value if available
525bc00e11SAndreas Gohr        if ($self) {
535bc00e11SAndreas Gohr            $this->renderer->listcontent_open();
54*7b7a9290SAndreas 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
785bc00e11SAndreas Gohr        if ($self) {
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)
88*7b7a9290SAndreas Gohr     * @param bool $showEmpty show a placeholder for empty values?
89ea5ad12aSMichael Grosse     */
90*7b7a9290SAndreas Gohr    protected function renderListItem($resultrow, $depth, $showEmpty = false)
91d6d97f60SAnna Dabrowska    {
92ea5ad12aSMichael Grosse        $sepbyheaders = $this->searchConfig->getConf()['sepbyheaders'];
93ea5ad12aSMichael Grosse        $headers = $this->searchConfig->getConf()['headers'];
94ea5ad12aSMichael Grosse
955bc00e11SAndreas Gohr        foreach ($resultrow as $index => $value) {
965bc00e11SAndreas Gohr            $column = $index + $depth; // the resultrow is shifted by the nesting depth
97ea5ad12aSMichael Grosse            if ($sepbyheaders && !empty($headers[$column])) {
985bc00e11SAndreas Gohr                $header = $headers[$column];
992c6e107cSMichael Grosse            } else {
1005bc00e11SAndreas Gohr                $header = '';
1015bc00e11SAndreas Gohr            }
1025bc00e11SAndreas Gohr
1035bc00e11SAndreas Gohr            if ($this->mode === 'xhtml') {
104*7b7a9290SAndreas Gohr                $this->renderValueXHTML($value, $header, $showEmpty);
1055bc00e11SAndreas Gohr            } else {
106*7b7a9290SAndreas Gohr                $this->renderValueGeneric($value, $header, $showEmpty);
107ea5ad12aSMichael Grosse            }
1082c6e107cSMichael Grosse        }
1092c6e107cSMichael Grosse    }
1105bc00e11SAndreas Gohr
1115bc00e11SAndreas Gohr    /**
1125bc00e11SAndreas Gohr     * Render the given Value in a XHTML renderer
1135bc00e11SAndreas Gohr     * @param Value $value
1145bc00e11SAndreas Gohr     * @param string $header
115*7b7a9290SAndreas Gohr     * @param bool $showEmpty
1165bc00e11SAndreas Gohr     * @return void
1175bc00e11SAndreas Gohr     */
118*7b7a9290SAndreas Gohr    protected function renderValueXHTML($value, $header, $showEmpty = false)
1195bc00e11SAndreas Gohr    {
1205bc00e11SAndreas Gohr        $attributes = [
1215bc00e11SAndreas Gohr            'data-struct-column' => strtolower($value->getColumn()->getFullQualifiedLabel()),
1225bc00e11SAndreas Gohr            'data-struct-type' => strtolower($value->getColumn()->getType()->getClass()),
1235bc00e11SAndreas Gohr            'class' => 'li', // default dokuwiki content wrapper
1245bc00e11SAndreas Gohr        ];
1255bc00e11SAndreas Gohr
1265bc00e11SAndreas Gohr        $this->renderer->doc .= sprintf('<div %s>', buildAttributes($attributes)); // wrapper
1275bc00e11SAndreas Gohr        if ($header !== '') {
1285bc00e11SAndreas Gohr            $this->renderer->doc .= sprintf('<span class="struct_header">%s</span> ', hsc($header));
1295bc00e11SAndreas Gohr        }
1305bc00e11SAndreas Gohr        $this->renderer->doc .= '<div class="struct_value">';
131*7b7a9290SAndreas Gohr        if ($value->isEmpty() && $showEmpty) {
132*7b7a9290SAndreas Gohr            $this->renderer->doc .= '<span class="struct_na">' . $this->helper->getLang('na') . '</span>';
133*7b7a9290SAndreas Gohr        } else {
134ea5ad12aSMichael Grosse            $value->render($this->renderer, $this->mode);
135*7b7a9290SAndreas Gohr        }
136ea5ad12aSMichael Grosse        $this->renderer->doc .= '</div>';
1375bc00e11SAndreas Gohr        $this->renderer->doc .= '</div> '; // wrapper
138ea5ad12aSMichael Grosse    }
1395bc00e11SAndreas Gohr
1405bc00e11SAndreas Gohr    /**
1415bc00e11SAndreas Gohr     * Render the given Value in any non-XHTML renderer
1425bc00e11SAndreas Gohr     * @param Value $value
1435bc00e11SAndreas Gohr     * @param string $header
1445bc00e11SAndreas Gohr     * @return void
1455bc00e11SAndreas Gohr     */
146*7b7a9290SAndreas Gohr    protected function renderValueGeneric($value, $header, $showEmpty = false)
1475bc00e11SAndreas Gohr    {
1485bc00e11SAndreas Gohr        $this->renderer->listcontent_open();
1495bc00e11SAndreas Gohr        if ($header !== '') $this->renderer->cdata($header . ' ');
150*7b7a9290SAndreas Gohr        if ($value->isEmpty() && $showEmpty) {
151*7b7a9290SAndreas Gohr            $this->renderer->cdata($this->helper->getLang('na'));
152*7b7a9290SAndreas Gohr        } else {
1535bc00e11SAndreas Gohr            $value->render($this->renderer, $this->mode);
154*7b7a9290SAndreas Gohr        }
1555bc00e11SAndreas Gohr        $this->renderer->listcontent_close();
156ea5ad12aSMichael Grosse    }
157ea5ad12aSMichael Grosse}
158