1<?php 2 3namespace dokuwiki\plugin\struct\meta; 4 5class AggregationCloud extends Aggregation 6{ 7 /** @var int */ 8 protected $max; 9 10 /** @var int */ 11 protected $min; 12 13 /** 14 * Initialize the Aggregation renderer and executes the search 15 * 16 * You need to call @param string $id 17 * @param string $mode 18 * @param \Doku_Renderer $renderer 19 * @param SearchConfig $searchConfig 20 * @see render() on the resulting object. 21 * 22 */ 23 public function postSearch() 24 { 25 $this->max = $this->result[0]['count']; 26 $this->min = end($this->result)['count']; 27 } 28 29 /** @inheritdoc */ 30 public function render($showNotFound = false) 31 { 32 $this->sortResults(); 33 $this->startList(); 34 foreach ($this->result as $result) { 35 $this->renderTag($result); 36 } 37 $this->finishList(); 38 } 39 40 /** 41 * Render a tag of the cloud 42 * 43 * @param ['tag' => Value, 'count' => int] $result 44 */ 45 protected function renderTag($result) 46 { 47 /** 48 * @var Value $value 49 */ 50 $value = $result['tag']; 51 $count = $result['count']; 52 if ($value->isEmpty()) { 53 return; 54 } 55 56 $type = strtolower($value->getColumn()->getType()->getClass()); 57 $weight = $this->getWeight($count, $this->min, $this->max); 58 59 if (!empty($this->data['target'])) { 60 $target = $this->data['target']; 61 } else { 62 global $INFO; 63 $target = $INFO['id']; 64 } 65 66 $tagValue = $value->getDisplayValue(); 67 if (is_array($tagValue)) { 68 $tagValue = $tagValue[0]; 69 } 70 $key = $value->getColumn()->getFullQualifiedLabel() . '='; 71 $filter = SearchConfigParameters::$PARAM_FILTER . '[' . urlencode($key) . ']=' . urlencode($tagValue); 72 73 $this->renderer->listitem_open(1); 74 $this->renderer->listcontent_open(); 75 76 if ($this->mode == 'xhtml') { 77 $this->renderer->doc .= 78 "<div style='font-size:$weight%' data-count='$count' class='cloudtag struct_$type'>"; 79 } 80 81 $showCount = $this->searchConfig->getConf()['summarize'] ? $count : 0; 82 $value->renderAsTagCloudLink($this->renderer, $this->mode, $target, $filter, $weight, $showCount); 83 84 if ($this->mode == 'xhtml') { 85 $this->renderer->doc .= '</div>'; 86 } 87 88 $this->renderer->listcontent_close(); 89 $this->renderer->listitem_close(); 90 } 91 92 /** 93 * This interpolates the weight between 70 and 150 based on $min, $max and $current 94 * 95 * @param int $current 96 * @param int $min 97 * @param int $max 98 * @return int 99 */ 100 protected function getWeight($current, $min, $max) 101 { 102 if ($min == $max) { 103 return 100; 104 } 105 return round(($current - $min) / ($max - $min) * 80 + 70); 106 } 107 108 /** 109 * Sort the list of results 110 */ 111 protected function sortResults() 112 { 113 usort($this->result, function ($a, $b) { 114 $asort = $a['tag']->getColumn()->getType()->getSortString($a['tag']); 115 $bsort = $b['tag']->getColumn()->getType()->getSortString($b['tag']); 116 if ($asort < $bsort) { 117 return -1; 118 } 119 if ($asort > $bsort) { 120 return 1; 121 } 122 return 0; 123 }); 124 } 125 126 protected function startList() 127 { 128 $this->renderer->listu_open(); 129 } 130 131 protected function finishList() 132 { 133 $this->renderer->listu_close(); 134 } 135} 136