1*0699ff47SMichael Grosse<?php 2*0699ff47SMichael Grosse 3*0699ff47SMichael Grossenamespace dokuwiki\plugin\struct\meta; 4*0699ff47SMichael Grosse 5*0699ff47SMichael Grosse 6*0699ff47SMichael Grosse/** 7*0699ff47SMichael Grosse * Class SearchCloud 8*0699ff47SMichael Grosse * 9*0699ff47SMichael Grosse * The same as @see SearchConfig, but executed a search that is not pid-focused 10*0699ff47SMichael Grosse * 11*0699ff47SMichael Grosse * @package dokuwiki\plugin\struct\meta 12*0699ff47SMichael Grosse */ 13*0699ff47SMichael Grosseclass SearchCloud extends SearchConfig { 14*0699ff47SMichael Grosse 15*0699ff47SMichael Grosse 16*0699ff47SMichael Grosse /** 17*0699ff47SMichael Grosse * Transform the set search parameters into a statement 18*0699ff47SMichael Grosse * 19*0699ff47SMichael Grosse * @return array ($sql, $opts) The SQL and parameters to execute 20*0699ff47SMichael Grosse */ 21*0699ff47SMichael Grosse public function getSQL() { 22*0699ff47SMichael Grosse if(!$this->columns) throw new StructException('nocolname'); 23*0699ff47SMichael Grosse 24*0699ff47SMichael Grosse $QB = new QueryBuilder(); 25*0699ff47SMichael Grosse reset($this->schemas); 26*0699ff47SMichael Grosse $schema = current($this->schemas); 27*0699ff47SMichael Grosse $datatable = 'data_' . $schema->getTable(); 28*0699ff47SMichael Grosse if(!$schema->isLookup()) { 29*0699ff47SMichael Grosse $QB->addTable('schema_assignments'); 30*0699ff47SMichael Grosse $QB->filters()->whereAnd("$datatable.pid = schema_assignments.pid"); 31*0699ff47SMichael Grosse $QB->filters()->whereAnd("schema_assignments.tbl = '{$schema->getTable()}'"); 32*0699ff47SMichael Grosse $QB->filters()->whereAnd("schema_assignments.assigned = 1"); 33*0699ff47SMichael Grosse $QB->filters()->whereAnd("GETACCESSLEVEL($datatable.pid) > 0"); 34*0699ff47SMichael Grosse $QB->filters()->whereAnd("PAGEEXISTS($datatable.pid) = 1"); 35*0699ff47SMichael Grosse } 36*0699ff47SMichael Grosse $QB->addTable($datatable); 37*0699ff47SMichael Grosse $QB->filters()->whereAnd("$datatable.latest = 1"); 38*0699ff47SMichael Grosse 39*0699ff47SMichael Grosse $col = $this->columns[0]; 40*0699ff47SMichael Grosse if($col->isMulti()) { 41*0699ff47SMichael Grosse $multitable = "multi_{$col->getTable()}"; 42*0699ff47SMichael Grosse $MN = 'M' . $col->getColref(); 43*0699ff47SMichael Grosse 44*0699ff47SMichael Grosse $QB->addLeftJoin( 45*0699ff47SMichael Grosse $datatable, 46*0699ff47SMichael Grosse $multitable, 47*0699ff47SMichael Grosse $MN, 48*0699ff47SMichael Grosse "$datatable.pid = $MN.pid AND 49*0699ff47SMichael Grosse $datatable.rev = $MN.rev AND 50*0699ff47SMichael Grosse $MN.colref = {$col->getColref()}" 51*0699ff47SMichael Grosse ); 52*0699ff47SMichael Grosse 53*0699ff47SMichael Grosse $col->getType()->select($QB, $MN, 'value', 'tag'); 54*0699ff47SMichael Grosse $colname = $MN . 'value'; 55*0699ff47SMichael Grosse } else { 56*0699ff47SMichael Grosse $col->getType()->select($QB, $datatable, $col->getColName(), 'tag'); 57*0699ff47SMichael Grosse $colname = $datatable . '.' . $col->getColName(); 58*0699ff47SMichael Grosse } 59*0699ff47SMichael Grosse $QB->addSelectStatement("COUNT($colname)", 'count'); 60*0699ff47SMichael Grosse $QB->addGroupByStatement('tag'); 61*0699ff47SMichael Grosse $QB->addOrderBy('tag'); 62*0699ff47SMichael Grosse 63*0699ff47SMichael Grosse return $QB->getSQL(); 64*0699ff47SMichael Grosse } 65*0699ff47SMichael Grosse 66*0699ff47SMichael Grosse /** 67*0699ff47SMichael Grosse * Execute this search and return the result 68*0699ff47SMichael Grosse * 69*0699ff47SMichael Grosse * The result is a two dimensional array of Value()s. 70*0699ff47SMichael Grosse * 71*0699ff47SMichael Grosse * This will always query for the full result (not using offset and limit) and then 72*0699ff47SMichael Grosse * return the wanted range, setting the count (@see getCount) to the whole result number 73*0699ff47SMichael Grosse * 74*0699ff47SMichael Grosse * @return Value[][] 75*0699ff47SMichael Grosse */ 76*0699ff47SMichael Grosse public function execute() { 77*0699ff47SMichael Grosse list($sql, $opts) = $this->getSQL(); 78*0699ff47SMichael Grosse 79*0699ff47SMichael Grosse /** @var \PDOStatement $res */ 80*0699ff47SMichael Grosse $res = $this->sqlite->query($sql, $opts); 81*0699ff47SMichael Grosse if($res === false) throw new StructException("SQL execution failed for\n\n$sql"); 82*0699ff47SMichael Grosse 83*0699ff47SMichael Grosse $this->result_pids = array(); 84*0699ff47SMichael Grosse $result = array(); 85*0699ff47SMichael Grosse $cursor = -1; 86*0699ff47SMichael Grosse while($row = $res->fetch(\PDO::FETCH_ASSOC)) { 87*0699ff47SMichael Grosse $cursor++; 88*0699ff47SMichael Grosse if($cursor < $this->range_begin) continue; 89*0699ff47SMichael Grosse if($this->range_end && $cursor >= $this->range_end) continue; 90*0699ff47SMichael Grosse 91*0699ff47SMichael Grosse // todo: check for min 92*0699ff47SMichael Grosse 93*0699ff47SMichael Grosse $row['tag'] = new Value($this->columns[0], $row['tag']); 94*0699ff47SMichael Grosse $result[] = $row; 95*0699ff47SMichael Grosse } 96*0699ff47SMichael Grosse 97*0699ff47SMichael Grosse $this->sqlite->res_close($res); 98*0699ff47SMichael Grosse $this->count = $cursor + 1; 99*0699ff47SMichael Grosse return $result; 100*0699ff47SMichael Grosse } 101*0699ff47SMichael Grosse} 102