10699ff47SMichael Grosse<?php 20699ff47SMichael Grosse 30699ff47SMichael Grossenamespace dokuwiki\plugin\struct\meta; 40699ff47SMichael Grosse 50699ff47SMichael Grosse 60699ff47SMichael Grosse/** 70699ff47SMichael Grosse * Class SearchCloud 80699ff47SMichael Grosse * 90699ff47SMichael Grosse * The same as @see SearchConfig, but executed a search that is not pid-focused 100699ff47SMichael Grosse * 110699ff47SMichael Grosse * @package dokuwiki\plugin\struct\meta 120699ff47SMichael Grosse */ 130699ff47SMichael Grosseclass SearchCloud extends SearchConfig { 140699ff47SMichael Grosse 150699ff47SMichael Grosse 160699ff47SMichael Grosse /** 170699ff47SMichael Grosse * Transform the set search parameters into a statement 180699ff47SMichael Grosse * 190699ff47SMichael Grosse * @return array ($sql, $opts) The SQL and parameters to execute 200699ff47SMichael Grosse */ 210699ff47SMichael Grosse public function getSQL() { 220699ff47SMichael Grosse if(!$this->columns) throw new StructException('nocolname'); 230699ff47SMichael Grosse 240699ff47SMichael Grosse $QB = new QueryBuilder(); 250699ff47SMichael Grosse reset($this->schemas); 260699ff47SMichael Grosse $schema = current($this->schemas); 270699ff47SMichael Grosse $datatable = 'data_' . $schema->getTable(); 280699ff47SMichael Grosse if(!$schema->isLookup()) { 290699ff47SMichael Grosse $QB->addTable('schema_assignments'); 300699ff47SMichael Grosse $QB->filters()->whereAnd("$datatable.pid = schema_assignments.pid"); 310699ff47SMichael Grosse $QB->filters()->whereAnd("schema_assignments.tbl = '{$schema->getTable()}'"); 320699ff47SMichael Grosse $QB->filters()->whereAnd("schema_assignments.assigned = 1"); 330699ff47SMichael Grosse $QB->filters()->whereAnd("GETACCESSLEVEL($datatable.pid) > 0"); 340699ff47SMichael Grosse $QB->filters()->whereAnd("PAGEEXISTS($datatable.pid) = 1"); 350699ff47SMichael Grosse } 360699ff47SMichael Grosse $QB->addTable($datatable); 370699ff47SMichael Grosse $QB->filters()->whereAnd("$datatable.latest = 1"); 380699ff47SMichael Grosse 390699ff47SMichael Grosse $col = $this->columns[0]; 400699ff47SMichael Grosse if($col->isMulti()) { 410699ff47SMichael Grosse $multitable = "multi_{$col->getTable()}"; 420699ff47SMichael Grosse $MN = 'M' . $col->getColref(); 430699ff47SMichael Grosse 440699ff47SMichael Grosse $QB->addLeftJoin( 450699ff47SMichael Grosse $datatable, 460699ff47SMichael Grosse $multitable, 470699ff47SMichael Grosse $MN, 480699ff47SMichael Grosse "$datatable.pid = $MN.pid AND 490699ff47SMichael Grosse $datatable.rev = $MN.rev AND 500699ff47SMichael Grosse $MN.colref = {$col->getColref()}" 510699ff47SMichael Grosse ); 520699ff47SMichael Grosse 530699ff47SMichael Grosse $col->getType()->select($QB, $MN, 'value', 'tag'); 540699ff47SMichael Grosse $colname = $MN . 'value'; 550699ff47SMichael Grosse } else { 560699ff47SMichael Grosse $col->getType()->select($QB, $datatable, $col->getColName(), 'tag'); 570699ff47SMichael Grosse $colname = $datatable . '.' . $col->getColName(); 580699ff47SMichael Grosse } 590699ff47SMichael Grosse $QB->addSelectStatement("COUNT($colname)", 'count'); 600699ff47SMichael Grosse $QB->addGroupByStatement('tag'); 61aafac1c1SMichael Grosse $QB->addOrderBy('count DESC'); 620699ff47SMichael Grosse 630699ff47SMichael Grosse return $QB->getSQL(); 640699ff47SMichael Grosse } 650699ff47SMichael Grosse 660699ff47SMichael Grosse /** 670699ff47SMichael Grosse * Execute this search and return the result 680699ff47SMichael Grosse * 690699ff47SMichael Grosse * The result is a two dimensional array of Value()s. 700699ff47SMichael Grosse * 710699ff47SMichael Grosse * This will always query for the full result (not using offset and limit) and then 720699ff47SMichael Grosse * return the wanted range, setting the count (@see getCount) to the whole result number 730699ff47SMichael Grosse * 740699ff47SMichael Grosse * @return Value[][] 750699ff47SMichael Grosse */ 760699ff47SMichael Grosse public function execute() { 770699ff47SMichael Grosse list($sql, $opts) = $this->getSQL(); 780699ff47SMichael Grosse 790699ff47SMichael Grosse /** @var \PDOStatement $res */ 800699ff47SMichael Grosse $res = $this->sqlite->query($sql, $opts); 810699ff47SMichael Grosse if($res === false) throw new StructException("SQL execution failed for\n\n$sql"); 820699ff47SMichael Grosse 830699ff47SMichael Grosse $this->result_pids = array(); 840699ff47SMichael Grosse $result = array(); 850699ff47SMichael Grosse $cursor = -1; 86*ae457e47SMichael Grosse 870699ff47SMichael Grosse while($row = $res->fetch(\PDO::FETCH_ASSOC)) { 88*ae457e47SMichael Grosse if (!empty($this->config['min']) && $this->config['min'] > $row['count']) { 89*ae457e47SMichael Grosse break; 90*ae457e47SMichael Grosse } 910699ff47SMichael Grosse $cursor++; 920699ff47SMichael Grosse if($cursor < $this->range_begin) continue; 930699ff47SMichael Grosse if($this->range_end && $cursor >= $this->range_end) continue; 940699ff47SMichael Grosse 950699ff47SMichael Grosse $row['tag'] = new Value($this->columns[0], $row['tag']); 960699ff47SMichael Grosse $result[] = $row; 970699ff47SMichael Grosse } 980699ff47SMichael Grosse 990699ff47SMichael Grosse $this->sqlite->res_close($res); 1000699ff47SMichael Grosse $this->count = $cursor + 1; 1010699ff47SMichael Grosse return $result; 1020699ff47SMichael Grosse } 1030699ff47SMichael Grosse} 104