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