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 __construct($id, $mode, \Doku_Renderer $renderer, SearchCloud $searchConfig) 24 { 25 parent::__construct($id, $mode, $renderer, $searchConfig); 26 27 $this->max = $this->result[0]['count']; 28 $this->min = end($this->result)['count']; 29 } 30 31 /** @inheritdoc */ 32 public function render($showNotFound = false) 33 { 34 $this->sortResults(); 35 $this->startScope(); 36 $this->startList(); 37 foreach ($this->result as $result) { 38 $this->renderTag($result); 39 } 40 $this->finishList(); 41 $this->finishScope(); 42 } 43 44 /** 45 * Adds additional info to document and renderer in XHTML mode 46 * 47 * @see finishScope() 48 */ 49 protected function startScope() 50 { 51 // wrapping div 52 if ($this->mode != 'xhtml') return; 53 $this->renderer->doc .= "<div class=\"structcloud\">"; 54 } 55 56 /** 57 * Closes the table and anything opened in startScope() 58 * 59 * @see startScope() 60 */ 61 protected function finishScope() 62 { 63 // wrapping div 64 if ($this->mode != 'xhtml') return; 65 $this->renderer->doc .= '</div>'; 66 } 67 68 /** 69 * Render a tag of the cloud 70 * 71 * @param ['tag' => Value, 'count' => int] $result 72 */ 73 protected function renderTag($result) 74 { 75 /** 76 * @var Value $value 77 */ 78 $value = $result['tag']; 79 $count = $result['count']; 80 if ($value->isEmpty()) { 81 return; 82 } 83 84 $type = strtolower($value->getColumn()->getType()->getClass()); 85 $weight = $this->getWeight($count, $this->min, $this->max); 86 87 if (!empty($this->data['target'])) { 88 $target = $this->data['target']; 89 } else { 90 global $INFO; 91 $target = $INFO['id']; 92 } 93 94 $tagValue = $value->getDisplayValue(); 95 if (is_array($tagValue)) { 96 $tagValue = $tagValue[0]; 97 } 98 $key = $value->getColumn()->getFullQualifiedLabel() . '='; 99 $filter = SearchConfigParameters::$PARAM_FILTER . '[' . urlencode($key) . ']=' . urlencode($tagValue); 100 101 $this->renderer->listitem_open(1); 102 $this->renderer->listcontent_open(); 103 104 if ($this->mode == 'xhtml') { 105 $this->renderer->doc .= 106 "<div style='font-size:$weight%' data-count='$count' class='cloudtag struct_$type'>"; 107 } 108 109 $value->renderAsTagCloudLink($this->renderer, $this->mode, $target, $filter, $weight); 110 111 if ($this->mode == 'xhtml') { 112 $this->renderer->doc .= '</div>'; 113 } 114 115 $this->renderer->listcontent_close(); 116 $this->renderer->listitem_close(); 117 } 118 119 /** 120 * This interpolates the weight between 70 and 150 based on $min, $max and $current 121 * 122 * @param int $current 123 * @param int $min 124 * @param int $max 125 * @return int 126 */ 127 protected function getWeight($current, $min, $max) 128 { 129 if ($min == $max) { 130 return 100; 131 } 132 return round(($current - $min) / ($max - $min) * 80 + 70); 133 } 134 135 /** 136 * Sort the list of results 137 */ 138 protected function sortResults() 139 { 140 usort($this->result, function ($a, $b) { 141 $asort = $a['tag']->getColumn()->getType()->getSortString($a['tag']); 142 $bsort = $b['tag']->getColumn()->getType()->getSortString($b['tag']); 143 if ($asort < $bsort) { 144 return -1; 145 } 146 if ($asort > $bsort) { 147 return 1; 148 } 149 return 0; 150 }); 151 } 152 153 protected function startList() 154 { 155 $this->renderer->listu_open(); 156 } 157 158 protected function finishList() 159 { 160 $this->renderer->listu_close(); 161 } 162} 163