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