1fa04b28cSMichael Grosse<?php 2*5282d027SMichael Grosse 3fa04b28cSMichael Grossenamespace dokuwiki\plugin\struct\meta; 4*5282d027SMichael Grosse 5fa04b28cSMichael Grosseclass AggregationCloud { 6*5282d027SMichael Grosse 7fa04b28cSMichael Grosse /** 8fa04b28cSMichael Grosse * @var string the page id of the page this is rendered to 9fa04b28cSMichael Grosse */ 10fa04b28cSMichael Grosse protected $id; 11*5282d027SMichael Grosse 12fa04b28cSMichael Grosse /** 13fa04b28cSMichael Grosse * @var string the Type of renderer used 14fa04b28cSMichael Grosse */ 15fa04b28cSMichael Grosse protected $mode; 16*5282d027SMichael Grosse 17fa04b28cSMichael Grosse /** 18fa04b28cSMichael Grosse * @var \Doku_Renderer the DokuWiki renderer used to create the output 19fa04b28cSMichael Grosse */ 20fa04b28cSMichael Grosse protected $renderer; 21*5282d027SMichael Grosse 22fa04b28cSMichael Grosse /** 23fa04b28cSMichael Grosse * @var SearchConfig the configured search - gives access to columns etc. 24fa04b28cSMichael Grosse */ 25fa04b28cSMichael Grosse protected $searchConfig; 26*5282d027SMichael Grosse 27fa04b28cSMichael Grosse /** 28fa04b28cSMichael Grosse * @var Column[] the list of columns to be displayed 29fa04b28cSMichael Grosse */ 30fa04b28cSMichael Grosse protected $columns; 31*5282d027SMichael Grosse 32fa04b28cSMichael Grosse /** 33fa04b28cSMichael Grosse * @var Value[][] the search result 34fa04b28cSMichael Grosse */ 35fa04b28cSMichael Grosse protected $result; 36*5282d027SMichael Grosse 37fa04b28cSMichael Grosse /** 38fa04b28cSMichael Grosse * @var int number of all results 39fa04b28cSMichael Grosse */ 40fa04b28cSMichael Grosse protected $resultCount; 41*5282d027SMichael Grosse 42fa04b28cSMichael Grosse /** 43fa04b28cSMichael Grosse * Initialize the Aggregation renderer and executes the search 44fa04b28cSMichael Grosse * 45fa04b28cSMichael Grosse * You need to call @see render() on the resulting object. 46fa04b28cSMichael Grosse * 47fa04b28cSMichael Grosse * @param string $id 48fa04b28cSMichael Grosse * @param string $mode 49fa04b28cSMichael Grosse * @param \Doku_Renderer $renderer 50fa04b28cSMichael Grosse * @param SearchConfig $searchConfig 51fa04b28cSMichael Grosse */ 520699ff47SMichael Grosse public function __construct($id, $mode, \Doku_Renderer $renderer, SearchCloud $searchConfig) { 53fa04b28cSMichael Grosse $this->id = $id; 54fa04b28cSMichael Grosse $this->mode = $mode; 55fa04b28cSMichael Grosse $this->renderer = $renderer; 56fa04b28cSMichael Grosse $this->searchConfig = $searchConfig; 57fa04b28cSMichael Grosse $this->data = $searchConfig->getConf(); 58fa04b28cSMichael Grosse $this->columns = $searchConfig->getColumns(); 590699ff47SMichael Grosse $this->result = $this->searchConfig->execute(); 600699ff47SMichael Grosse $this->resultCount = $this->searchConfig->getCount(); 61aafac1c1SMichael Grosse 62aafac1c1SMichael Grosse $this->max = $this->result[0]['count']; 63aafac1c1SMichael Grosse $this->min = end($this->result)['count']; 64fa04b28cSMichael Grosse } 65fa04b28cSMichael Grosse 66fa04b28cSMichael Grosse /** 67fa04b28cSMichael Grosse * Create the table on the renderer 68fa04b28cSMichael Grosse */ 69fa04b28cSMichael Grosse public function render() { 70fa04b28cSMichael Grosse $this->startScope(); 71fa04b28cSMichael Grosse $this->renderer->doc .= '<ul>'; 72fa04b28cSMichael Grosse foreach ($this->result as $result) { 7333bd00e9SMichael Grosse $this->renderTag($result); 74fa04b28cSMichael Grosse } 75fa04b28cSMichael Grosse $this->renderer->doc .= '</ul>'; 76fa04b28cSMichael Grosse $this->finishScope(); 77fa04b28cSMichael Grosse return; 78fa04b28cSMichael Grosse } 79*5282d027SMichael Grosse 80fa04b28cSMichael Grosse /** 81fa04b28cSMichael Grosse * Adds additional info to document and renderer in XHTML mode 82fa04b28cSMichael Grosse * 83fa04b28cSMichael Grosse * @see finishScope() 84fa04b28cSMichael Grosse */ 85fa04b28cSMichael Grosse protected function startScope() { 86fa04b28cSMichael Grosse // wrapping div 87fa04b28cSMichael Grosse if($this->mode != 'xhtml') return; 88be2ae900SMichael Grosse $this->renderer->doc .= "<div class=\"structcloud\">"; 89fa04b28cSMichael Grosse } 90*5282d027SMichael Grosse 91fa04b28cSMichael Grosse /** 92fa04b28cSMichael Grosse * Closes the table and anything opened in startScope() 93fa04b28cSMichael Grosse * 94fa04b28cSMichael Grosse * @see startScope() 95fa04b28cSMichael Grosse */ 96fa04b28cSMichael Grosse protected function finishScope() { 97fa04b28cSMichael Grosse // wrapping div 98fa04b28cSMichael Grosse if($this->mode != 'xhtml') return; 99fa04b28cSMichael Grosse $this->renderer->doc .= '</div>'; 100fa04b28cSMichael Grosse } 101aafac1c1SMichael Grosse 10233bd00e9SMichael Grosse /** 10333bd00e9SMichael Grosse * Render a tag of the cloud 10433bd00e9SMichael Grosse * 10533bd00e9SMichael Grosse * @param ['tag' => Value, 'count' => int] $result 10633bd00e9SMichael Grosse */ 10733bd00e9SMichael Grosse protected function renderTag($result) { 108fa04b28cSMichael Grosse /** 109fa04b28cSMichael Grosse * @var Value $value 110fa04b28cSMichael Grosse */ 111fa04b28cSMichael Grosse $value = $result['tag']; 112fa04b28cSMichael Grosse $count = $result['count']; 113aafac1c1SMichael Grosse $weight = $this->getWeight($count, $this->min, $this->max); 114*5282d027SMichael Grosse $type = 'struct_' . strtolower($value->getColumn()->getType()->getClass()); 115fa04b28cSMichael Grosse if ($value->isEmpty()) { 116fa04b28cSMichael Grosse return; 117fa04b28cSMichael Grosse } 118fa04b28cSMichael Grosse 119ce8676aeSMichael Grosse $tagValue = $value->getDisplayValue(); 120ce8676aeSMichael Grosse if (empty($tagValue)) { 121ce8676aeSMichael Grosse $tagValue = $value->getRawValue(); 122ce8676aeSMichael Grosse } 123ce8676aeSMichael Grosse if (is_array($tagValue)) { 124ce8676aeSMichael Grosse $tagValue = $tagValue[0]; 125fa04b28cSMichael Grosse } 126fa04b28cSMichael Grosse $schema = $this->data['schemas'][0][0]; 127fa04b28cSMichael Grosse $col = $value->getColumn()->getLabel(); 128fa04b28cSMichael Grosse $this->renderer->doc .= '<li><div class="li">'; 1294c969d82SMichael Grosse $this->renderer->doc .= "<div style='font-size:$weight%' data-count='$count' class='cloudtag $type'>"; 1304c969d82SMichael Grosse 131ce8676aeSMichael Grosse $this->renderer->internallink("?flt[$schema.$col*~]=" . urlencode($tagValue),$tagValue); 132fa04b28cSMichael Grosse $this->renderer->doc .= '</div>'; 133fa04b28cSMichael Grosse $this->renderer->doc .= '</div></li>'; 134fa04b28cSMichael Grosse } 135aafac1c1SMichael Grosse 136aafac1c1SMichael Grosse /** 137aafac1c1SMichael Grosse * This interpolates the weight between 70 and 150 based on $min, $max and $current 138aafac1c1SMichael Grosse * 139aafac1c1SMichael Grosse * @param int $current 140aafac1c1SMichael Grosse * @param int $min 141aafac1c1SMichael Grosse * @param int $max 142aafac1c1SMichael Grosse * @return float|int 143aafac1c1SMichael Grosse */ 144aafac1c1SMichael Grosse protected function getWeight($current, $min, $max) { 145aafac1c1SMichael Grosse if ($min == $max) { 146aafac1c1SMichael Grosse return 100; 147aafac1c1SMichael Grosse } 148aafac1c1SMichael Grosse return ($current - $min)/($max - $min) * 80 + 70; 149aafac1c1SMichael Grosse } 150fa04b28cSMichael Grosse} 151