xref: /plugin/struct/meta/AggregationCloud.php (revision bfb78ce36191746735158574eab0f078874f52f2)
1fa04b28cSMichael Grosse<?php
25282d027SMichael Grosse
3fa04b28cSMichael Grossenamespace dokuwiki\plugin\struct\meta;
45282d027SMichael Grosse
5d90aa848SAndreas Gohrclass AggregationCloud extends Aggregation
6d6d97f60SAnna Dabrowska{
7d90aa848SAndreas Gohr    /** @var int */
8d90aa848SAndreas Gohr    protected $max;
95282d027SMichael Grosse
10d90aa848SAndreas Gohr    /** @var int */
11d90aa848SAndreas 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    {
25d90aa848SAndreas 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
31d90aa848SAndreas Gohr    /** @inheritdoc */
32d90aa848SAndreas Gohr    public function render($showNotFound = false)
33d6d97f60SAnna Dabrowska    {
348b4531cfSMichael Grosse        $this->sortResults();
35c7dd6b6aSMichael Grosse        $this->startList();
36fa04b28cSMichael Grosse        foreach ($this->result as $result) {
3733bd00e9SMichael Grosse            $this->renderTag($result);
38fa04b28cSMichael Grosse        }
39c7dd6b6aSMichael Grosse        $this->finishList();
40fa04b28cSMichael Grosse    }
41aafac1c1SMichael Grosse
4233bd00e9SMichael Grosse    /**
4333bd00e9SMichael Grosse     * Render a tag of the cloud
4433bd00e9SMichael Grosse     *
4533bd00e9SMichael Grosse     * @param ['tag' => Value, 'count' => int] $result
4633bd00e9SMichael Grosse     */
47d6d97f60SAnna Dabrowska    protected function renderTag($result)
48d6d97f60SAnna Dabrowska    {
49fa04b28cSMichael Grosse        /**
50fa04b28cSMichael Grosse         * @var Value $value
51fa04b28cSMichael Grosse         */
52fa04b28cSMichael Grosse        $value = $result['tag'];
53fa04b28cSMichael Grosse        $count = $result['count'];
54fa04b28cSMichael Grosse        if ($value->isEmpty()) {
55fa04b28cSMichael Grosse            return;
56fa04b28cSMichael Grosse        }
57fa04b28cSMichael Grosse
58c7dd6b6aSMichael Grosse        $type = strtolower($value->getColumn()->getType()->getClass());
59c7dd6b6aSMichael Grosse        $weight = $this->getWeight($count, $this->min, $this->max);
608e54e6f4SMichael Grosse
6185edf4f2SMichael Grosse        if (!empty($this->data['target'])) {
6285edf4f2SMichael Grosse            $target = $this->data['target'];
6385edf4f2SMichael Grosse        } else {
6485edf4f2SMichael Grosse            global $INFO;
6585edf4f2SMichael Grosse            $target = $INFO['id'];
6685edf4f2SMichael Grosse        }
678e54e6f4SMichael Grosse
68ce8676aeSMichael Grosse        $tagValue = $value->getDisplayValue();
69ce8676aeSMichael Grosse        if (is_array($tagValue)) {
70ce8676aeSMichael Grosse            $tagValue = $tagValue[0];
71fa04b28cSMichael Grosse        }
7257775e30SSzymon Olewniczak        $key = $value->getColumn()->getFullQualifiedLabel() . '=';
7343d76406SSzymon Olewniczak        $filter = SearchConfigParameters::$PARAM_FILTER . '[' . urlencode($key) . ']=' . urlencode($tagValue);
74c7dd6b6aSMichael Grosse
75da11327aSMichael Grosse        $this->renderer->listitem_open(1);
76da11327aSMichael Grosse        $this->renderer->listcontent_open();
77da11327aSMichael Grosse
78262c0fc6SMichael Grosse        if ($this->mode == 'xhtml') {
7917a3a578SAndreas Gohr            $this->renderer->doc .=
8017a3a578SAndreas Gohr                "<div style='font-size:$weight%' data-count='$count' class='cloudtag struct_$type'>";
818e54e6f4SMichael Grosse        }
828e54e6f4SMichael Grosse
83*bfb78ce3SAnna Dabrowska        $showCount = $this->searchConfig->getConf()['summarize'] ? $count : 0;
84*bfb78ce3SAnna Dabrowska        $value->renderAsTagCloudLink($this->renderer, $this->mode, $target, $filter, $weight, $showCount);
85262c0fc6SMichael Grosse
86262c0fc6SMichael Grosse        if ($this->mode == 'xhtml') {
87c7dd6b6aSMichael Grosse            $this->renderer->doc .= '</div>';
88fa04b28cSMichael Grosse        }
89da11327aSMichael Grosse
90da11327aSMichael Grosse        $this->renderer->listcontent_close();
91da11327aSMichael Grosse        $this->renderer->listitem_close();
92262c0fc6SMichael Grosse    }
93aafac1c1SMichael Grosse
94aafac1c1SMichael Grosse    /**
95aafac1c1SMichael Grosse     * This interpolates the weight between 70 and 150 based on $min, $max and $current
96aafac1c1SMichael Grosse     *
97aafac1c1SMichael Grosse     * @param int $current
98aafac1c1SMichael Grosse     * @param int $min
99aafac1c1SMichael Grosse     * @param int $max
1008e54e6f4SMichael Grosse     * @return int
101aafac1c1SMichael Grosse     */
102d6d97f60SAnna Dabrowska    protected function getWeight($current, $min, $max)
103d6d97f60SAnna Dabrowska    {
104aafac1c1SMichael Grosse        if ($min == $max) {
105aafac1c1SMichael Grosse            return 100;
106aafac1c1SMichael Grosse        }
1078e54e6f4SMichael Grosse        return round(($current - $min) / ($max - $min) * 80 + 70);
108aafac1c1SMichael Grosse    }
1098b4531cfSMichael Grosse
1108b4531cfSMichael Grosse    /**
1118b4531cfSMichael Grosse     * Sort the list of results
1128b4531cfSMichael Grosse     */
113d6d97f60SAnna Dabrowska    protected function sortResults()
114d6d97f60SAnna Dabrowska    {
1158b4531cfSMichael Grosse        usort($this->result, function ($a, $b) {
116d560ea13SMichael Grosse            $asort = $a['tag']->getColumn()->getType()->getSortString($a['tag']);
117d560ea13SMichael Grosse            $bsort = $b['tag']->getColumn()->getType()->getSortString($b['tag']);
118d560ea13SMichael Grosse            if ($asort < $bsort) {
1198b4531cfSMichael Grosse                return -1;
1208b4531cfSMichael Grosse            }
121d560ea13SMichael Grosse            if ($asort > $bsort) {
1228b4531cfSMichael Grosse                return 1;
1238b4531cfSMichael Grosse            }
1248b4531cfSMichael Grosse            return 0;
1258b4531cfSMichael Grosse        });
1268b4531cfSMichael Grosse    }
1278b4531cfSMichael Grosse
128d6d97f60SAnna Dabrowska    protected function startList()
129d6d97f60SAnna Dabrowska    {
130c7dd6b6aSMichael Grosse        $this->renderer->listu_open();
131c7dd6b6aSMichael Grosse    }
132c7dd6b6aSMichael Grosse
133d6d97f60SAnna Dabrowska    protected function finishList()
134d6d97f60SAnna Dabrowska    {
135c7dd6b6aSMichael Grosse        $this->renderer->listu_close();
136c7dd6b6aSMichael Grosse    }
137fa04b28cSMichael Grosse}
138