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