xref: /plugin/struct/meta/SearchCloud.php (revision 86cfd13c2f01260f5eb9c5ee71067132dfa708c4)
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