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