xref: /plugin/struct/meta/SearchCloud.php (revision 24eec657c05b0d72bf071b3cc0551de15e9d5f32)
1<?php
2
3namespace dokuwiki\plugin\struct\meta;
4
5/**
6 * Class SearchCloud
7 *
8 * The same as @see SearchConfig, but executed a search that is not pid-focused
9 *
10 * @package dokuwiki\plugin\struct\meta
11 */
12class SearchCloud extends SearchConfig
13{
14    protected $limit = '';
15
16    /**
17     * We do not have pagination in clouds, so we can work with a limit within SQL
18     *
19     * @param int $limit
20     */
21    public function setLimit($limit)
22    {
23        $this->limit = " LIMIT $limit";
24    }
25
26    /**
27     * @inheritdoc
28     */
29    protected function runSQLBuilder()
30    {
31        $sqlBuilder = new SearchSQLBuilder();
32        $sqlBuilder->setSelectLatest($this->selectLatest);
33        $sqlBuilder->addSchemas($this->schemas, false);
34        $this->addTagSelector($sqlBuilder);
35        $sqlBuilder->getQueryBuilder()->addGroupByStatement('tag');
36        $sqlBuilder->getQueryBuilder()->addOrderBy('count DESC');
37        $sqlBuilder->addFilters($this->filter);
38        return $sqlBuilder;
39    }
40
41    /**
42     * Add the tag selector to the SQLBuilder
43     */
44    protected function addTagSelector(SearchSQLBuilder $builder)
45    {
46        $QB = $builder->getQueryBuilder();
47
48        $col = $this->columns[0];
49        $datatable = "data_{$col->getTable()}";
50
51        if ($col->isMulti()) {
52            $multitable = "multi_{$col->getTable()}";
53            $MN = $QB->generateTableAlias('M');
54
55            $QB->addLeftJoin(
56                $datatable,
57                $multitable,
58                $MN,
59                "$datatable.pid = $MN.pid AND
60                     $datatable.rid = $MN.rid AND
61                     $datatable.rev = $MN.rev AND
62                     $MN.colref = {$col->getColref()}"
63            );
64
65            $col->getType()->select($QB, $MN, 'value', 'tag');
66            $colname = $MN . '.value';
67        } else {
68            $col->getType()->select($QB, $datatable, $col->getColName(), 'tag');
69            $colname = $datatable . '.' . $col->getColName();
70        }
71        $QB->addSelectStatement("COUNT($colname)", 'count');
72    }
73
74
75    /**
76     * Execute this search and return the result
77     *
78     * Because the cloud uses a different search, we omit calling
79     * getResult() und run() methods of the parent class, and return the result array directly.
80     *
81     * @return Value[][]
82     */
83    public function getRows()
84    {
85        [$sql, $opts] = $this->getSQL();
86
87        /** @var \PDOStatement $res */
88        $res = $this->sqlite->query($sql, $opts);
89        if ($res === false) throw new StructException("SQL execution failed for\n\n$sql");
90
91        $result = [];
92        $rows = $res->fetchAll(\PDO::FETCH_ASSOC);
93
94        foreach ($rows as $row) {
95            if (!empty($this->config['min']) && $this->config['min'] > $row['count']) {
96                break;
97            }
98
99            $row['tag'] = new Value($this->columns[0], $row['tag']);
100            $result[] = $row;
101        }
102
103        $res->closeCursor();
104        return $result;
105    }
106}
107