xref: /plugin/struct/meta/AggregationCloud.php (revision 5282d02798805d00ec98ef97fa74696698136f57)
1fa04b28cSMichael Grosse<?php
2*5282d027SMichael Grosse
3fa04b28cSMichael Grossenamespace dokuwiki\plugin\struct\meta;
4*5282d027SMichael Grosse
5fa04b28cSMichael Grosseclass AggregationCloud {
6*5282d027SMichael Grosse
7fa04b28cSMichael Grosse    /**
8fa04b28cSMichael Grosse     * @var string the page id of the page this is rendered to
9fa04b28cSMichael Grosse     */
10fa04b28cSMichael Grosse    protected $id;
11*5282d027SMichael Grosse
12fa04b28cSMichael Grosse    /**
13fa04b28cSMichael Grosse     * @var string the Type of renderer used
14fa04b28cSMichael Grosse     */
15fa04b28cSMichael Grosse    protected $mode;
16*5282d027SMichael Grosse
17fa04b28cSMichael Grosse    /**
18fa04b28cSMichael Grosse     * @var \Doku_Renderer the DokuWiki renderer used to create the output
19fa04b28cSMichael Grosse     */
20fa04b28cSMichael Grosse    protected $renderer;
21*5282d027SMichael Grosse
22fa04b28cSMichael Grosse    /**
23fa04b28cSMichael Grosse     * @var SearchConfig the configured search - gives access to columns etc.
24fa04b28cSMichael Grosse     */
25fa04b28cSMichael Grosse    protected $searchConfig;
26*5282d027SMichael Grosse
27fa04b28cSMichael Grosse    /**
28fa04b28cSMichael Grosse     * @var Column[] the list of columns to be displayed
29fa04b28cSMichael Grosse     */
30fa04b28cSMichael Grosse    protected $columns;
31*5282d027SMichael Grosse
32fa04b28cSMichael Grosse    /**
33fa04b28cSMichael Grosse     * @var  Value[][] the search result
34fa04b28cSMichael Grosse     */
35fa04b28cSMichael Grosse    protected $result;
36*5282d027SMichael Grosse
37fa04b28cSMichael Grosse    /**
38fa04b28cSMichael Grosse     * @var int number of all results
39fa04b28cSMichael Grosse     */
40fa04b28cSMichael Grosse    protected $resultCount;
41*5282d027SMichael Grosse
42fa04b28cSMichael Grosse    /**
43fa04b28cSMichael Grosse     * Initialize the Aggregation renderer and executes the search
44fa04b28cSMichael Grosse     *
45fa04b28cSMichael Grosse     * You need to call @see render() on the resulting object.
46fa04b28cSMichael Grosse     *
47fa04b28cSMichael Grosse     * @param string $id
48fa04b28cSMichael Grosse     * @param string $mode
49fa04b28cSMichael Grosse     * @param \Doku_Renderer $renderer
50fa04b28cSMichael Grosse     * @param SearchConfig $searchConfig
51fa04b28cSMichael Grosse     */
520699ff47SMichael Grosse    public function __construct($id, $mode, \Doku_Renderer $renderer, SearchCloud $searchConfig) {
53fa04b28cSMichael Grosse        $this->id = $id;
54fa04b28cSMichael Grosse        $this->mode = $mode;
55fa04b28cSMichael Grosse        $this->renderer = $renderer;
56fa04b28cSMichael Grosse        $this->searchConfig = $searchConfig;
57fa04b28cSMichael Grosse        $this->data = $searchConfig->getConf();
58fa04b28cSMichael Grosse        $this->columns = $searchConfig->getColumns();
590699ff47SMichael Grosse        $this->result = $this->searchConfig->execute();
600699ff47SMichael Grosse        $this->resultCount = $this->searchConfig->getCount();
61aafac1c1SMichael Grosse
62aafac1c1SMichael Grosse        $this->max = $this->result[0]['count'];
63aafac1c1SMichael Grosse        $this->min = end($this->result)['count'];
64fa04b28cSMichael Grosse    }
65fa04b28cSMichael Grosse
66fa04b28cSMichael Grosse    /**
67fa04b28cSMichael Grosse     * Create the table on the renderer
68fa04b28cSMichael Grosse     */
69fa04b28cSMichael Grosse    public function render() {
70fa04b28cSMichael Grosse        $this->startScope();
71fa04b28cSMichael Grosse        $this->renderer->doc .= '<ul>';
72fa04b28cSMichael Grosse        foreach ($this->result as $result) {
7333bd00e9SMichael Grosse            $this->renderTag($result);
74fa04b28cSMichael Grosse        }
75fa04b28cSMichael Grosse        $this->renderer->doc .= '</ul>';
76fa04b28cSMichael Grosse        $this->finishScope();
77fa04b28cSMichael Grosse        return;
78fa04b28cSMichael Grosse    }
79*5282d027SMichael Grosse
80fa04b28cSMichael Grosse    /**
81fa04b28cSMichael Grosse     * Adds additional info to document and renderer in XHTML mode
82fa04b28cSMichael Grosse     *
83fa04b28cSMichael Grosse     * @see finishScope()
84fa04b28cSMichael Grosse     */
85fa04b28cSMichael Grosse    protected function startScope() {
86fa04b28cSMichael Grosse        // wrapping div
87fa04b28cSMichael Grosse        if($this->mode != 'xhtml') return;
88be2ae900SMichael Grosse        $this->renderer->doc .= "<div class=\"structcloud\">";
89fa04b28cSMichael Grosse    }
90*5282d027SMichael Grosse
91fa04b28cSMichael Grosse    /**
92fa04b28cSMichael Grosse     * Closes the table and anything opened in startScope()
93fa04b28cSMichael Grosse     *
94fa04b28cSMichael Grosse     * @see startScope()
95fa04b28cSMichael Grosse     */
96fa04b28cSMichael Grosse    protected function finishScope() {
97fa04b28cSMichael Grosse        // wrapping div
98fa04b28cSMichael Grosse        if($this->mode != 'xhtml') return;
99fa04b28cSMichael Grosse        $this->renderer->doc .= '</div>';
100fa04b28cSMichael Grosse    }
101aafac1c1SMichael Grosse
10233bd00e9SMichael Grosse    /**
10333bd00e9SMichael Grosse     * Render a tag of the cloud
10433bd00e9SMichael Grosse     *
10533bd00e9SMichael Grosse     * @param ['tag' => Value, 'count' => int] $result
10633bd00e9SMichael Grosse     */
10733bd00e9SMichael Grosse    protected function renderTag($result) {
108fa04b28cSMichael Grosse        /**
109fa04b28cSMichael Grosse         * @var Value $value
110fa04b28cSMichael Grosse         */
111fa04b28cSMichael Grosse        $value = $result['tag'];
112fa04b28cSMichael Grosse        $count = $result['count'];
113aafac1c1SMichael Grosse        $weight = $this->getWeight($count, $this->min, $this->max);
114*5282d027SMichael Grosse        $type = 'struct_' . strtolower($value->getColumn()->getType()->getClass());
115fa04b28cSMichael Grosse        if ($value->isEmpty()) {
116fa04b28cSMichael Grosse            return;
117fa04b28cSMichael Grosse        }
118fa04b28cSMichael Grosse
119ce8676aeSMichael Grosse        $tagValue = $value->getDisplayValue();
120ce8676aeSMichael Grosse        if (empty($tagValue)) {
121ce8676aeSMichael Grosse            $tagValue = $value->getRawValue();
122ce8676aeSMichael Grosse        }
123ce8676aeSMichael Grosse        if (is_array($tagValue)) {
124ce8676aeSMichael Grosse            $tagValue = $tagValue[0];
125fa04b28cSMichael Grosse        }
126fa04b28cSMichael Grosse        $schema = $this->data['schemas'][0][0];
127fa04b28cSMichael Grosse        $col = $value->getColumn()->getLabel();
128fa04b28cSMichael Grosse        $this->renderer->doc .= '<li><div class="li">';
1294c969d82SMichael Grosse        $this->renderer->doc .= "<div style='font-size:$weight%' data-count='$count' class='cloudtag $type'>";
1304c969d82SMichael Grosse
131ce8676aeSMichael Grosse        $this->renderer->internallink("?flt[$schema.$col*~]=" . urlencode($tagValue),$tagValue);
132fa04b28cSMichael Grosse        $this->renderer->doc .= '</div>';
133fa04b28cSMichael Grosse        $this->renderer->doc .= '</div></li>';
134fa04b28cSMichael Grosse    }
135aafac1c1SMichael Grosse
136aafac1c1SMichael Grosse    /**
137aafac1c1SMichael Grosse     * This interpolates the weight between 70 and 150 based on $min, $max and $current
138aafac1c1SMichael Grosse     *
139aafac1c1SMichael Grosse     * @param int $current
140aafac1c1SMichael Grosse     * @param int $min
141aafac1c1SMichael Grosse     * @param int $max
142aafac1c1SMichael Grosse     * @return float|int
143aafac1c1SMichael Grosse     */
144aafac1c1SMichael Grosse    protected function getWeight($current, $min, $max) {
145aafac1c1SMichael Grosse        if ($min == $max) {
146aafac1c1SMichael Grosse            return 100;
147aafac1c1SMichael Grosse        }
148aafac1c1SMichael Grosse        return ($current - $min)/($max - $min) * 80 + 70;
149aafac1c1SMichael Grosse    }
150fa04b28cSMichael Grosse}
151