10699ff47SMichael Grosse<?php 20699ff47SMichael Grosse 30699ff47SMichael Grossenamespace dokuwiki\plugin\struct\meta; 40699ff47SMichael Grosse 50699ff47SMichael Grosse/** 60699ff47SMichael Grosse * Class SearchCloud 70699ff47SMichael Grosse * 80699ff47SMichael Grosse * The same as @see SearchConfig, but executed a search that is not pid-focused 90699ff47SMichael Grosse * 100699ff47SMichael Grosse * @package dokuwiki\plugin\struct\meta 110699ff47SMichael Grosse */ 12d6d97f60SAnna Dabrowskaclass SearchCloud extends SearchConfig 13d6d97f60SAnna Dabrowska{ 143ec19891SMichael Grosse protected $limit = ''; 153ec19891SMichael 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 */ 21dea51657SAnna Dabrowska public function getSQL() 22d6d97f60SAnna Dabrowska { 230699ff47SMichael Grosse if (!$this->columns) throw new StructException('nocolname'); 240699ff47SMichael Grosse 250699ff47SMichael Grosse $QB = new QueryBuilder(); 260699ff47SMichael Grosse reset($this->schemas); 270699ff47SMichael Grosse $schema = current($this->schemas); 280699ff47SMichael Grosse $datatable = 'data_' . $schema->getTable(); 29dea51657SAnna Dabrowska 300699ff47SMichael Grosse $QB->addTable($datatable); 31dea51657SAnna Dabrowska 32dea51657SAnna Dabrowska // add conditional page clauses if pid has a value 33dea51657SAnna Dabrowska $subAnd = $QB->filters()->whereSubAnd(); 34dea51657SAnna Dabrowska $subAnd->whereAnd("$datatable.pid = ''"); 35*7234bfb1Ssplitbrain 36dea51657SAnna Dabrowska $subOr = $subAnd->whereSubOr(); 37dea51657SAnna Dabrowska $subOr->whereAnd("GETACCESSLEVEL($datatable.pid) > 0"); 38dea51657SAnna Dabrowska $subOr->whereAnd("PAGEEXISTS($datatable.pid) = 1"); 39b871825aSAndreas Gohr $subOr->whereSubOr() 40b871825aSAndreas Gohr ->whereAnd('ASSIGNED == 1') 41b871825aSAndreas Gohr ->whereSubOr() 42b871825aSAndreas Gohr ->whereAnd("$datatable.rid > 0") 43b871825aSAndreas Gohr ->whereAnd("ASSIGNED IS NULL"); 44dea51657SAnna Dabrowska 45dea51657SAnna Dabrowska // add conditional schema assignment check 46dea51657SAnna Dabrowska $QB->addLeftJoin( 47dea51657SAnna Dabrowska $datatable, 48dea51657SAnna Dabrowska 'schema_assignments', 49dea51657SAnna Dabrowska '', 50dea51657SAnna Dabrowska "$datatable.pid != '' 51dea51657SAnna Dabrowska AND $datatable.pid = schema_assignments.pid 5215df5922SAnna Dabrowska AND schema_assignments.tbl = '{$schema->getTable()}'" 53dea51657SAnna Dabrowska ); 54dea51657SAnna Dabrowska 550699ff47SMichael Grosse $QB->filters()->whereAnd("$datatable.latest = 1"); 565b133c8dSMichael Große $QB->filters()->where('AND', 'tag IS NOT \'\''); 570699ff47SMichael Grosse 580699ff47SMichael Grosse $col = $this->columns[0]; 590699ff47SMichael Grosse if ($col->isMulti()) { 600699ff47SMichael Grosse $multitable = "multi_{$col->getTable()}"; 6187feee46SMichael Grosse $MN = $QB->generateTableAlias('M'); 620699ff47SMichael Grosse 630699ff47SMichael Grosse $QB->addLeftJoin( 640699ff47SMichael Grosse $datatable, 650699ff47SMichael Grosse $multitable, 660699ff47SMichael Grosse $MN, 6715df5922SAnna Dabrowska "$datatable.pid = $MN.pid AND 6815df5922SAnna Dabrowska $datatable.rid = $MN.rid AND 690699ff47SMichael Grosse $datatable.rev = $MN.rev AND 700699ff47SMichael Grosse $MN.colref = {$col->getColref()}" 710699ff47SMichael Grosse ); 720699ff47SMichael Grosse 730699ff47SMichael Grosse $col->getType()->select($QB, $MN, 'value', 'tag'); 745f11f83eSMichael Grosse $colname = $MN . '.value'; 750699ff47SMichael Grosse } else { 760699ff47SMichael Grosse $col->getType()->select($QB, $datatable, $col->getColName(), 'tag'); 770699ff47SMichael Grosse $colname = $datatable . '.' . $col->getColName(); 780699ff47SMichael Grosse } 790699ff47SMichael Grosse $QB->addSelectStatement("COUNT($colname)", 'count'); 8015df5922SAnna Dabrowska $QB->addSelectColumn('schema_assignments', 'assigned', 'ASSIGNED'); 810699ff47SMichael Grosse $QB->addGroupByStatement('tag'); 82aafac1c1SMichael Grosse $QB->addOrderBy('count DESC'); 830699ff47SMichael Grosse 84*7234bfb1Ssplitbrain [$sql, $opts] = $QB->getSQL(); 853ec19891SMichael Grosse return [$sql . $this->limit, $opts]; 860699ff47SMichael Grosse } 870699ff47SMichael Grosse 880699ff47SMichael Grosse /** 893ec19891SMichael Grosse * We do not have pagination in clouds, so we can work with a limit within SQL 903ec19891SMichael Grosse * 913ec19891SMichael Grosse * @param int $limit 923ec19891SMichael Grosse */ 93d6d97f60SAnna Dabrowska public function setLimit($limit) 94d6d97f60SAnna Dabrowska { 953ec19891SMichael Grosse $this->limit = " LIMIT $limit"; 963ec19891SMichael Grosse } 973ec19891SMichael Grosse 983ec19891SMichael Grosse /** 990699ff47SMichael Grosse * Execute this search and return the result 1000699ff47SMichael Grosse * 1010699ff47SMichael Grosse * The result is a two dimensional array of Value()s. 1020699ff47SMichael Grosse * 1030699ff47SMichael Grosse * @return Value[][] 1040699ff47SMichael Grosse */ 105dea51657SAnna Dabrowska public function execute() 106d6d97f60SAnna Dabrowska { 107*7234bfb1Ssplitbrain [$sql, $opts] = $this->getSQL(); 1080699ff47SMichael Grosse 1090699ff47SMichael Grosse /** @var \PDOStatement $res */ 1100699ff47SMichael Grosse $res = $this->sqlite->query($sql, $opts); 1110699ff47SMichael Grosse if ($res === false) throw new StructException("SQL execution failed for\n\n$sql"); 1120699ff47SMichael Grosse 1133ec19891SMichael Grosse $result = []; 11479b29326SAnna Dabrowska $rows = $res->fetchAll(\PDO::FETCH_ASSOC); 115ae457e47SMichael Grosse 1163ec19891SMichael Grosse foreach ($rows as $row) { 117ae457e47SMichael Grosse if (!empty($this->config['min']) && $this->config['min'] > $row['count']) { 118ae457e47SMichael Grosse break; 119ae457e47SMichael Grosse } 1200699ff47SMichael Grosse 1210699ff47SMichael Grosse $row['tag'] = new Value($this->columns[0], $row['tag']); 1220699ff47SMichael Grosse $result[] = $row; 1230699ff47SMichael Grosse } 1240699ff47SMichael Grosse 12579b29326SAnna Dabrowska $res->closeCursor(); 1263ec19891SMichael Grosse $this->count = count($result); 1270699ff47SMichael Grosse return $result; 1280699ff47SMichael Grosse } 1290699ff47SMichael Grosse} 130