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