1fa04b28cSMichael Grosse<?php 2fa04b28cSMichael Grossenamespace dokuwiki\plugin\struct\meta; 3fa04b28cSMichael Grosseclass AggregationCloud { 4fa04b28cSMichael Grosse /** 5fa04b28cSMichael Grosse * @var string the page id of the page this is rendered to 6fa04b28cSMichael Grosse */ 7fa04b28cSMichael Grosse protected $id; 8fa04b28cSMichael Grosse /** 9fa04b28cSMichael Grosse * @var string the Type of renderer used 10fa04b28cSMichael Grosse */ 11fa04b28cSMichael Grosse protected $mode; 12fa04b28cSMichael Grosse /** 13fa04b28cSMichael Grosse * @var \Doku_Renderer the DokuWiki renderer used to create the output 14fa04b28cSMichael Grosse */ 15fa04b28cSMichael Grosse protected $renderer; 16fa04b28cSMichael Grosse /** 17fa04b28cSMichael Grosse * @var SearchConfig the configured search - gives access to columns etc. 18fa04b28cSMichael Grosse */ 19fa04b28cSMichael Grosse protected $searchConfig; 20fa04b28cSMichael Grosse /** 21fa04b28cSMichael Grosse * @var Column[] the list of columns to be displayed 22fa04b28cSMichael Grosse */ 23fa04b28cSMichael Grosse protected $columns; 24fa04b28cSMichael Grosse /** 25fa04b28cSMichael Grosse * @var Value[][] the search result 26fa04b28cSMichael Grosse */ 27fa04b28cSMichael Grosse protected $result; 28fa04b28cSMichael Grosse /** 29fa04b28cSMichael Grosse * @var int number of all results 30fa04b28cSMichael Grosse */ 31fa04b28cSMichael Grosse protected $resultCount; 32fa04b28cSMichael Grosse /** 33fa04b28cSMichael Grosse * @var string[] the result PIDs for each row 34fa04b28cSMichael Grosse */ 35fa04b28cSMichael Grosse protected $resultPIDs; 36fa04b28cSMichael Grosse /** 37fa04b28cSMichael Grosse * @var array for summing up columns 38fa04b28cSMichael Grosse */ 39fa04b28cSMichael Grosse protected $sums; 40fa04b28cSMichael Grosse /** 41fa04b28cSMichael Grosse * @var bool skip full table when no results found 42fa04b28cSMichael Grosse */ 43fa04b28cSMichael Grosse protected $simplenone = true; 44fa04b28cSMichael Grosse /** 45fa04b28cSMichael Grosse * @todo we might be able to get rid of this helper and move this to SearchConfig 46fa04b28cSMichael Grosse * @var \helper_plugin_struct_config 47fa04b28cSMichael Grosse */ 48fa04b28cSMichael Grosse protected $helper; 49fa04b28cSMichael Grosse /** 50fa04b28cSMichael Grosse * Initialize the Aggregation renderer and executes the search 51fa04b28cSMichael Grosse * 52fa04b28cSMichael Grosse * You need to call @see render() on the resulting object. 53fa04b28cSMichael Grosse * 54fa04b28cSMichael Grosse * @param string $id 55fa04b28cSMichael Grosse * @param string $mode 56fa04b28cSMichael Grosse * @param \Doku_Renderer $renderer 57fa04b28cSMichael Grosse * @param SearchConfig $searchConfig 58fa04b28cSMichael Grosse */ 590699ff47SMichael Grosse public function __construct($id, $mode, \Doku_Renderer $renderer, SearchCloud $searchConfig) { 60fa04b28cSMichael Grosse $this->id = $id; 61fa04b28cSMichael Grosse $this->mode = $mode; 62fa04b28cSMichael Grosse $this->renderer = $renderer; 63fa04b28cSMichael Grosse $this->searchConfig = $searchConfig; 64fa04b28cSMichael Grosse $this->data = $searchConfig->getConf(); 65fa04b28cSMichael Grosse $this->columns = $searchConfig->getColumns(); 660699ff47SMichael Grosse $this->result = $this->searchConfig->execute(); 670699ff47SMichael Grosse $this->resultCount = $this->searchConfig->getCount(); 68fa04b28cSMichael Grosse $this->helper = plugin_load('helper', 'struct_config'); 69*aafac1c1SMichael Grosse 70*aafac1c1SMichael Grosse $this->max = $this->result[0]['count']; 71*aafac1c1SMichael Grosse $this->min = end($this->result)['count']; 72fa04b28cSMichael Grosse } 73fa04b28cSMichael Grosse 74fa04b28cSMichael Grosse /** 75fa04b28cSMichael Grosse * Create the table on the renderer 76fa04b28cSMichael Grosse */ 77fa04b28cSMichael Grosse public function render() { 78fa04b28cSMichael Grosse $this->startScope(); 79fa04b28cSMichael Grosse $this->renderer->doc .= '<ul>'; 80fa04b28cSMichael Grosse foreach ($this->result as $result) { 81fa04b28cSMichael Grosse $this->renderResult($result); 82fa04b28cSMichael Grosse } 83fa04b28cSMichael Grosse $this->renderer->doc .= '</ul>'; 84fa04b28cSMichael Grosse $this->finishScope(); 85fa04b28cSMichael Grosse return; 86fa04b28cSMichael Grosse } 87fa04b28cSMichael Grosse /** 88fa04b28cSMichael Grosse * Adds additional info to document and renderer in XHTML mode 89fa04b28cSMichael Grosse * 90fa04b28cSMichael Grosse * @see finishScope() 91fa04b28cSMichael Grosse */ 92fa04b28cSMichael Grosse protected function startScope() { 93fa04b28cSMichael Grosse // unique identifier for this aggregation 94fa04b28cSMichael Grosse $this->renderer->info['struct_cloud_hash'] = md5(var_export($this->data, true)); 95fa04b28cSMichael Grosse // wrapping div 96fa04b28cSMichael Grosse if($this->mode != 'xhtml') return; 97fa04b28cSMichael Grosse $this->renderer->doc .= "<div class=\"structaggregation cloudaggregation\">"; 98fa04b28cSMichael Grosse } 99fa04b28cSMichael Grosse /** 100fa04b28cSMichael Grosse * Closes the table and anything opened in startScope() 101fa04b28cSMichael Grosse * 102fa04b28cSMichael Grosse * @see startScope() 103fa04b28cSMichael Grosse */ 104fa04b28cSMichael Grosse protected function finishScope() { 105fa04b28cSMichael Grosse // remove identifier from renderer again 106fa04b28cSMichael Grosse if(isset($this->renderer->info['struct_cloud_hash'])) { 107fa04b28cSMichael Grosse unset($this->renderer->info['struct_cloud_hash']); 108fa04b28cSMichael Grosse } 109fa04b28cSMichael Grosse // wrapping div 110fa04b28cSMichael Grosse if($this->mode != 'xhtml') return; 111fa04b28cSMichael Grosse $this->renderer->doc .= '</div>'; 112fa04b28cSMichael Grosse } 113*aafac1c1SMichael Grosse 114fa04b28cSMichael Grosse protected function renderResult($result) { 115fa04b28cSMichael Grosse /** 116fa04b28cSMichael Grosse * @var Value $value 117fa04b28cSMichael Grosse */ 118fa04b28cSMichael Grosse $value = $result['tag']; 119fa04b28cSMichael Grosse $count = $result['count']; 120*aafac1c1SMichael Grosse $weight = $this->getWeight($count, $this->min, $this->max); 121*aafac1c1SMichael Grosse $type = strtolower($value->getColumn()->getType()->getClass()); 122fa04b28cSMichael Grosse if ($value->isEmpty()) { 123fa04b28cSMichael Grosse return; 124fa04b28cSMichael Grosse } 125fa04b28cSMichael Grosse 126fa04b28cSMichael Grosse $raw = $value->getRawValue(); 127fa04b28cSMichael Grosse if (is_array($raw)) { 128fa04b28cSMichael Grosse $raw = $raw[0]; 129fa04b28cSMichael Grosse } 130fa04b28cSMichael Grosse $schema = $this->data['schemas'][0][0]; 131fa04b28cSMichael Grosse $col = $value->getColumn()->getLabel(); 132fa04b28cSMichael Grosse $this->renderer->doc .= '<li><div class="li">'; 133*aafac1c1SMichael Grosse $this->renderer->doc .= "<div data-weight='$weight' data-count='$count' class='cloudtag $type'>"; 134fa04b28cSMichael Grosse //$value->render($this->renderer, $this->mode); 1351719449cSMichael Grosse $this->renderer->internallink("?flt[$schema.$col*~]=" . urlencode($raw),$raw); 136fa04b28cSMichael Grosse if ($column < $this->resultCount) { 137fa04b28cSMichael Grosse $this->renderer->doc .= ' '; 138fa04b28cSMichael Grosse } 139fa04b28cSMichael Grosse $this->renderer->doc .= '</div>'; 140fa04b28cSMichael Grosse $this->renderer->doc .= '</div></li>'; 141fa04b28cSMichael Grosse } 142*aafac1c1SMichael Grosse 143*aafac1c1SMichael Grosse /** 144*aafac1c1SMichael Grosse * This interpolates the weight between 70 and 150 based on $min, $max and $current 145*aafac1c1SMichael Grosse * 146*aafac1c1SMichael Grosse * @param int $current 147*aafac1c1SMichael Grosse * @param int $min 148*aafac1c1SMichael Grosse * @param int $max 149*aafac1c1SMichael Grosse * @return float|int 150*aafac1c1SMichael Grosse */ 151*aafac1c1SMichael Grosse protected function getWeight($current, $min, $max) { 152*aafac1c1SMichael Grosse if ($min == $max) { 153*aafac1c1SMichael Grosse return 100; 154*aafac1c1SMichael Grosse } 155*aafac1c1SMichael Grosse return ($current - $min)/($max - $min) * 80 + 70; 156*aafac1c1SMichael Grosse } 157fa04b28cSMichael Grosse} 158