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 153ec19891SMichael Grosse protected $limit = ''; 163ec19891SMichael Grosse 170699ff47SMichael Grosse 180699ff47SMichael Grosse /** 190699ff47SMichael Grosse * Transform the set search parameters into a statement 200699ff47SMichael Grosse * 21*86cfd13cSAnna Dabrowska * @param string $idColumn Column on which to join tables 220699ff47SMichael Grosse * @return array ($sql, $opts) The SQL and parameters to execute 230699ff47SMichael Grosse */ 24*86cfd13cSAnna Dabrowska public function getSQL($idColumn) { 250699ff47SMichael Grosse if(!$this->columns) throw new StructException('nocolname'); 260699ff47SMichael Grosse 270699ff47SMichael Grosse $QB = new QueryBuilder(); 280699ff47SMichael Grosse reset($this->schemas); 290699ff47SMichael Grosse $schema = current($this->schemas); 300699ff47SMichael Grosse $datatable = 'data_' . $schema->getTable(); 31*86cfd13cSAnna Dabrowska if($idColumn === 'pid') { 320699ff47SMichael Grosse $QB->addTable('schema_assignments'); 330699ff47SMichael Grosse $QB->filters()->whereAnd("$datatable.pid = schema_assignments.pid"); 340699ff47SMichael Grosse $QB->filters()->whereAnd("schema_assignments.tbl = '{$schema->getTable()}'"); 350699ff47SMichael Grosse $QB->filters()->whereAnd("schema_assignments.assigned = 1"); 360699ff47SMichael Grosse $QB->filters()->whereAnd("GETACCESSLEVEL($datatable.pid) > 0"); 370699ff47SMichael Grosse $QB->filters()->whereAnd("PAGEEXISTS($datatable.pid) = 1"); 380699ff47SMichael Grosse } 390699ff47SMichael Grosse $QB->addTable($datatable); 400699ff47SMichael Grosse $QB->filters()->whereAnd("$datatable.latest = 1"); 415b133c8dSMichael Große $QB->filters()->where('AND', 'tag IS NOT \'\''); 420699ff47SMichael Grosse 430699ff47SMichael Grosse $col = $this->columns[0]; 440699ff47SMichael Grosse if($col->isMulti()) { 450699ff47SMichael Grosse $multitable = "multi_{$col->getTable()}"; 4687feee46SMichael Grosse $MN = $QB->generateTableAlias('M'); 470699ff47SMichael Grosse 480699ff47SMichael Grosse $QB->addLeftJoin( 490699ff47SMichael Grosse $datatable, 500699ff47SMichael Grosse $multitable, 510699ff47SMichael Grosse $MN, 52*86cfd13cSAnna Dabrowska "$datatable.$idColumn = $MN.$idColumn AND 530699ff47SMichael Grosse $datatable.rev = $MN.rev AND 540699ff47SMichael Grosse $MN.colref = {$col->getColref()}" 550699ff47SMichael Grosse ); 560699ff47SMichael Grosse 570699ff47SMichael Grosse $col->getType()->select($QB, $MN, 'value', 'tag'); 585f11f83eSMichael Grosse $colname = $MN . '.value'; 590699ff47SMichael Grosse } else { 600699ff47SMichael Grosse $col->getType()->select($QB, $datatable, $col->getColName(), 'tag'); 610699ff47SMichael Grosse $colname = $datatable . '.' . $col->getColName(); 620699ff47SMichael Grosse } 630699ff47SMichael Grosse $QB->addSelectStatement("COUNT($colname)", 'count'); 640699ff47SMichael Grosse $QB->addGroupByStatement('tag'); 65aafac1c1SMichael Grosse $QB->addOrderBy('count DESC'); 660699ff47SMichael Grosse 673ec19891SMichael Grosse list($sql, $opts) = $QB->getSQL(); 683ec19891SMichael Grosse return [$sql . $this->limit, $opts]; 690699ff47SMichael Grosse } 700699ff47SMichael Grosse 710699ff47SMichael Grosse /** 723ec19891SMichael Grosse * We do not have pagination in clouds, so we can work with a limit within SQL 733ec19891SMichael Grosse * 743ec19891SMichael Grosse * @param int $limit 753ec19891SMichael Grosse */ 763ec19891SMichael Grosse public function setLimit($limit) { 773ec19891SMichael Grosse $this->limit = " LIMIT $limit"; 783ec19891SMichael Grosse } 793ec19891SMichael Grosse 803ec19891SMichael Grosse /** 810699ff47SMichael Grosse * Execute this search and return the result 820699ff47SMichael Grosse * 830699ff47SMichael Grosse * The result is a two dimensional array of Value()s. 840699ff47SMichael Grosse * 85*86cfd13cSAnna Dabrowska * @param string $idColumn Column on which to join tables 860699ff47SMichael Grosse * @return Value[][] 870699ff47SMichael Grosse */ 88*86cfd13cSAnna Dabrowska public function execute($idColumn) { 89*86cfd13cSAnna Dabrowska list($sql, $opts) = $this->getSQL($idColumn); 900699ff47SMichael Grosse 910699ff47SMichael Grosse /** @var \PDOStatement $res */ 920699ff47SMichael Grosse $res = $this->sqlite->query($sql, $opts); 930699ff47SMichael Grosse if($res === false) throw new StructException("SQL execution failed for\n\n$sql"); 940699ff47SMichael Grosse 953ec19891SMichael Grosse $result = []; 963ec19891SMichael Grosse $rows = $this->sqlite->res2arr($res); 97ae457e47SMichael Grosse 983ec19891SMichael Grosse foreach ($rows as $row) { 99ae457e47SMichael Grosse if (!empty($this->config['min']) && $this->config['min'] > $row['count']) { 100ae457e47SMichael Grosse break; 101ae457e47SMichael Grosse } 1020699ff47SMichael Grosse 1030699ff47SMichael Grosse $row['tag'] = new Value($this->columns[0], $row['tag']); 1040699ff47SMichael Grosse $result[] = $row; 1050699ff47SMichael Grosse } 1060699ff47SMichael Grosse 1070699ff47SMichael Grosse $this->sqlite->res_close($res); 1083ec19891SMichael Grosse $this->count = count($result); 1090699ff47SMichael Grosse return $result; 1100699ff47SMichael Grosse } 1110699ff47SMichael Grosse} 112