xref: /plugin/struct/meta/Aggregation.php (revision 4b00515c41c61eceb0528f49dcb3789d99bb3399)
1<?php
2
3namespace dokuwiki\plugin\struct\meta;
4
5/**
6 * Base contract for Aggregations
7 *
8 * @package dokuwiki\plugin\struct\meta
9 */
10abstract class Aggregation
11{
12    /** @var string the page id of the page this is rendered to */
13    protected $id;
14
15    /** @var string the Type of renderer used */
16    protected $mode;
17
18    /** @var \Doku_Renderer the DokuWiki renderer used to create the output */
19    protected $renderer;
20
21    /** @var SearchConfig the configured search - gives access to columns etc. */
22    protected $searchConfig;
23
24    /** @var Column[] the list of columns to be displayed */
25    protected $columns;
26
27    /** @var  Value[][] the search result */
28    protected $result;
29
30    /** @var int number of all results */
31    protected $resultCount;
32
33    /**
34     * @todo we might be able to get rid of this helper and move this to SearchConfig
35     * @var \helper_plugin_struct_config
36     */
37    protected $helper;
38
39    /**
40     * @var array the original configuration data
41     */
42    protected $data;
43
44    /**
45     * Initialize the Aggregation renderer and executes the search
46     *
47     * You need to call startScope(), render() and finishScope() on the resulting object.
48     *
49     * @param string $id The page this is rendered to
50     * @param string $mode The renderer format
51     * @param \Doku_Renderer $renderer The renderer to use for output
52     * @param SearchConfig $searchConfig The configured search object to use for displaying the data
53     */
54    public function __construct($id, $mode, \Doku_Renderer $renderer, SearchConfig $searchConfig)
55    {
56        $this->id = $id;
57        $this->mode = $mode;
58        $this->renderer = $renderer;
59        $this->searchConfig = $searchConfig;
60        $this->data = $searchConfig->getConf();
61        $this->columns = $searchConfig->getColumns();
62        $this->result = $this->searchConfig->execute();
63        $this->resultCount = $this->searchConfig->getCount();
64        $this->helper = plugin_load('helper', 'struct_config');
65    }
66
67    /**
68     * Returns the page id the aggregation is used on
69     */
70    public function getID()
71    {
72        return $this->id;
73    }
74
75    /**
76     * Return the list of classes that should be added to the scope when rendering XHTML
77     *
78     * @return string[]
79     */
80    public function getScopeClasses()
81    {
82        // we're all aggregations
83        $classes = ['structaggregation'];
84
85        // which type of aggregation are we?
86        $class = get_class($this);
87        $class = substr($class, strrpos($class, "\\") + 1);
88        $class = strtolower($class);
89        $classes[] = 'struct' . $class;
90
91        // config options
92        if ($this->data['nesting']) {
93            $classes[] = 'is-nested';
94        }
95        if ($this->data['index']) {
96            $classes[] = 'is-indexed';
97        }
98
99        // custom classes
100        $classes = array_merge($classes, $this->data['classes']);
101        return $classes;
102    }
103
104    /**
105     * Render the actual output to the renderer
106     *
107     * @param bool $showNotFound show a not found message when no data available?
108     */
109    abstract public function render($showNotFound = false);
110
111    /**
112     * Adds additional info to document and renderer in XHTML mode
113     *
114     * Called before render()
115     *
116     * @see finishScope()
117     */
118    public function startScope()
119    {
120        if ($this->mode == 'xhtml') {
121            $classes = $this->getScopeClasses();
122
123            $hash = $this->renderer->info['struct_table_hash'] ?? '';
124            $id = $hash ? " id=\"$hash\" " : '';
125
126            $this->renderer->doc .= '<div ' . $id . 'class="' . implode(' ', $classes) . '">';
127        }
128    }
129
130    /**
131     * Closes anything opened in startScope()
132     *
133     * Called after render()
134     *
135     * @see startScope()
136     */
137    public function finishScope()
138    {
139        if ($this->mode == 'xhtml') {
140            $this->renderer->doc .= '</div>';
141        }
142    }
143}
144