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