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