xref: /plugin/struct/meta/AggregationCloud.php (revision d90aa848684950ae06490f12279278db183f4fa5)
1fa04b28cSMichael Grosse<?php
25282d027SMichael Grosse
3fa04b28cSMichael Grossenamespace dokuwiki\plugin\struct\meta;
45282d027SMichael Grosse
5*d90aa848SAndreas Gohrclass AggregationCloud extends Aggregation
6d6d97f60SAnna Dabrowska{
7*d90aa848SAndreas Gohr    /** @var int */
8*d90aa848SAndreas Gohr    protected $max;
95282d027SMichael Grosse
10*d90aa848SAndreas Gohr    /** @var int */
11*d90aa848SAndreas Gohr    protected $min;
125282d027SMichael Grosse
13fa04b28cSMichael Grosse    /**
14fa04b28cSMichael Grosse     * Initialize the Aggregation renderer and executes the search
15fa04b28cSMichael Grosse     *
160549dcc5SAndreas Gohr     * You need to call @param string $id
17fa04b28cSMichael Grosse     * @param string $mode
18fa04b28cSMichael Grosse     * @param \Doku_Renderer $renderer
19fa04b28cSMichael Grosse     * @param SearchConfig $searchConfig
200549dcc5SAndreas Gohr     * @see render() on the resulting object.
210549dcc5SAndreas Gohr     *
22fa04b28cSMichael Grosse     */
23d6d97f60SAnna Dabrowska    public function __construct($id, $mode, \Doku_Renderer $renderer, SearchCloud $searchConfig)
24d6d97f60SAnna Dabrowska    {
25*d90aa848SAndreas Gohr        parent::__construct($id, $mode, $renderer, $searchConfig);
26aafac1c1SMichael Grosse
27aafac1c1SMichael Grosse        $this->max = $this->result[0]['count'];
28aafac1c1SMichael Grosse        $this->min = end($this->result)['count'];
29fa04b28cSMichael Grosse    }
30fa04b28cSMichael Grosse
31*d90aa848SAndreas Gohr    /** @inheritdoc */
32*d90aa848SAndreas Gohr    public function render($showNotFound = false)
33d6d97f60SAnna Dabrowska    {
348b4531cfSMichael Grosse        $this->sortResults();
35fa04b28cSMichael Grosse        $this->startScope();
36c7dd6b6aSMichael Grosse        $this->startList();
37fa04b28cSMichael Grosse        foreach ($this->result as $result) {
3833bd00e9SMichael Grosse            $this->renderTag($result);
39fa04b28cSMichael Grosse        }
40c7dd6b6aSMichael Grosse        $this->finishList();
41fa04b28cSMichael Grosse        $this->finishScope();
42fa04b28cSMichael Grosse    }
435282d027SMichael Grosse
44fa04b28cSMichael Grosse    /**
45fa04b28cSMichael Grosse     * Adds additional info to document and renderer in XHTML mode
46fa04b28cSMichael Grosse     *
47fa04b28cSMichael Grosse     * @see finishScope()
48fa04b28cSMichael Grosse     */
49d6d97f60SAnna Dabrowska    protected function startScope()
50d6d97f60SAnna Dabrowska    {
51fa04b28cSMichael Grosse        // wrapping div
52fa04b28cSMichael Grosse        if ($this->mode != 'xhtml') return;
53be2ae900SMichael Grosse        $this->renderer->doc .= "<div class=\"structcloud\">";
54fa04b28cSMichael Grosse    }
555282d027SMichael Grosse
56fa04b28cSMichael Grosse    /**
57fa04b28cSMichael Grosse     * Closes the table and anything opened in startScope()
58fa04b28cSMichael Grosse     *
59fa04b28cSMichael Grosse     * @see startScope()
60fa04b28cSMichael Grosse     */
61d6d97f60SAnna Dabrowska    protected function finishScope()
62d6d97f60SAnna Dabrowska    {
63fa04b28cSMichael Grosse        // wrapping div
64fa04b28cSMichael Grosse        if ($this->mode != 'xhtml') return;
65fa04b28cSMichael Grosse        $this->renderer->doc .= '</div>';
66fa04b28cSMichael Grosse    }
67aafac1c1SMichael Grosse
6833bd00e9SMichael Grosse    /**
6933bd00e9SMichael Grosse     * Render a tag of the cloud
7033bd00e9SMichael Grosse     *
7133bd00e9SMichael Grosse     * @param ['tag' => Value, 'count' => int] $result
7233bd00e9SMichael Grosse     */
73d6d97f60SAnna Dabrowska    protected function renderTag($result)
74d6d97f60SAnna Dabrowska    {
75fa04b28cSMichael Grosse        /**
76fa04b28cSMichael Grosse         * @var Value $value
77fa04b28cSMichael Grosse         */
78fa04b28cSMichael Grosse        $value = $result['tag'];
79fa04b28cSMichael Grosse        $count = $result['count'];
80fa04b28cSMichael Grosse        if ($value->isEmpty()) {
81fa04b28cSMichael Grosse            return;
82fa04b28cSMichael Grosse        }
83fa04b28cSMichael Grosse
84c7dd6b6aSMichael Grosse        $type = strtolower($value->getColumn()->getType()->getClass());
85c7dd6b6aSMichael Grosse        $weight = $this->getWeight($count, $this->min, $this->max);
868e54e6f4SMichael Grosse
8785edf4f2SMichael Grosse        if (!empty($this->data['target'])) {
8885edf4f2SMichael Grosse            $target = $this->data['target'];
8985edf4f2SMichael Grosse        } else {
9085edf4f2SMichael Grosse            global $INFO;
9185edf4f2SMichael Grosse            $target = $INFO['id'];
9285edf4f2SMichael Grosse        }
938e54e6f4SMichael Grosse
94ce8676aeSMichael Grosse        $tagValue = $value->getDisplayValue();
95ce8676aeSMichael Grosse        if (is_array($tagValue)) {
96ce8676aeSMichael Grosse            $tagValue = $tagValue[0];
97fa04b28cSMichael Grosse        }
9857775e30SSzymon Olewniczak        $key = $value->getColumn()->getFullQualifiedLabel() . '=';
9943d76406SSzymon Olewniczak        $filter = SearchConfigParameters::$PARAM_FILTER . '[' . urlencode($key) . ']=' . urlencode($tagValue);
100c7dd6b6aSMichael Grosse
101da11327aSMichael Grosse        $this->renderer->listitem_open(1);
102da11327aSMichael Grosse        $this->renderer->listcontent_open();
103da11327aSMichael Grosse
104262c0fc6SMichael Grosse        if ($this->mode == 'xhtml') {
10517a3a578SAndreas Gohr            $this->renderer->doc .=
10617a3a578SAndreas Gohr                "<div style='font-size:$weight%' data-count='$count' class='cloudtag struct_$type'>";
1078e54e6f4SMichael Grosse        }
1088e54e6f4SMichael Grosse
109262c0fc6SMichael Grosse        $value->renderAsTagCloudLink($this->renderer, $this->mode, $target, $filter, $weight);
110262c0fc6SMichael Grosse
111262c0fc6SMichael Grosse        if ($this->mode == 'xhtml') {
112c7dd6b6aSMichael Grosse            $this->renderer->doc .= '</div>';
113fa04b28cSMichael Grosse        }
114da11327aSMichael Grosse
115da11327aSMichael Grosse        $this->renderer->listcontent_close();
116da11327aSMichael Grosse        $this->renderer->listitem_close();
117262c0fc6SMichael Grosse    }
118aafac1c1SMichael Grosse
119aafac1c1SMichael Grosse    /**
120aafac1c1SMichael Grosse     * This interpolates the weight between 70 and 150 based on $min, $max and $current
121aafac1c1SMichael Grosse     *
122aafac1c1SMichael Grosse     * @param int $current
123aafac1c1SMichael Grosse     * @param int $min
124aafac1c1SMichael Grosse     * @param int $max
1258e54e6f4SMichael Grosse     * @return int
126aafac1c1SMichael Grosse     */
127d6d97f60SAnna Dabrowska    protected function getWeight($current, $min, $max)
128d6d97f60SAnna Dabrowska    {
129aafac1c1SMichael Grosse        if ($min == $max) {
130aafac1c1SMichael Grosse            return 100;
131aafac1c1SMichael Grosse        }
1328e54e6f4SMichael Grosse        return round(($current - $min) / ($max - $min) * 80 + 70);
133aafac1c1SMichael Grosse    }
1348b4531cfSMichael Grosse
1358b4531cfSMichael Grosse    /**
1368b4531cfSMichael Grosse     * Sort the list of results
1378b4531cfSMichael Grosse     */
138d6d97f60SAnna Dabrowska    protected function sortResults()
139d6d97f60SAnna Dabrowska    {
1408b4531cfSMichael Grosse        usort($this->result, function ($a, $b) {
141d560ea13SMichael Grosse            $asort = $a['tag']->getColumn()->getType()->getSortString($a['tag']);
142d560ea13SMichael Grosse            $bsort = $b['tag']->getColumn()->getType()->getSortString($b['tag']);
143d560ea13SMichael Grosse            if ($asort < $bsort) {
1448b4531cfSMichael Grosse                return -1;
1458b4531cfSMichael Grosse            }
146d560ea13SMichael Grosse            if ($asort > $bsort) {
1478b4531cfSMichael Grosse                return 1;
1488b4531cfSMichael Grosse            }
1498b4531cfSMichael Grosse            return 0;
1508b4531cfSMichael Grosse        });
1518b4531cfSMichael Grosse    }
1528b4531cfSMichael Grosse
153d6d97f60SAnna Dabrowska    protected function startList()
154d6d97f60SAnna Dabrowska    {
155c7dd6b6aSMichael Grosse        $this->renderer->listu_open();
156c7dd6b6aSMichael Grosse    }
157c7dd6b6aSMichael Grosse
158d6d97f60SAnna Dabrowska    protected function finishList()
159d6d97f60SAnna Dabrowska    {
160c7dd6b6aSMichael Grosse        $this->renderer->listu_close();
161c7dd6b6aSMichael Grosse    }
162fa04b28cSMichael Grosse}
163