xref: /plugin/struct/meta/SearchCloud.php (revision ae457e47a1744c9f5a3cf2830772650e25b46df1)
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
150699ff47SMichael Grosse
160699ff47SMichael Grosse    /**
170699ff47SMichael Grosse     * Transform the set search parameters into a statement
180699ff47SMichael Grosse     *
190699ff47SMichael Grosse     * @return array ($sql, $opts) The SQL and parameters to execute
200699ff47SMichael Grosse     */
210699ff47SMichael Grosse    public function getSQL() {
220699ff47SMichael Grosse        if(!$this->columns) throw new StructException('nocolname');
230699ff47SMichael Grosse
240699ff47SMichael Grosse        $QB = new QueryBuilder();
250699ff47SMichael Grosse        reset($this->schemas);
260699ff47SMichael Grosse        $schema = current($this->schemas);
270699ff47SMichael Grosse        $datatable = 'data_' . $schema->getTable();
280699ff47SMichael Grosse        if(!$schema->isLookup()) {
290699ff47SMichael Grosse            $QB->addTable('schema_assignments');
300699ff47SMichael Grosse            $QB->filters()->whereAnd("$datatable.pid = schema_assignments.pid");
310699ff47SMichael Grosse            $QB->filters()->whereAnd("schema_assignments.tbl = '{$schema->getTable()}'");
320699ff47SMichael Grosse            $QB->filters()->whereAnd("schema_assignments.assigned = 1");
330699ff47SMichael Grosse            $QB->filters()->whereAnd("GETACCESSLEVEL($datatable.pid) > 0");
340699ff47SMichael Grosse            $QB->filters()->whereAnd("PAGEEXISTS($datatable.pid) = 1");
350699ff47SMichael Grosse        }
360699ff47SMichael Grosse        $QB->addTable($datatable);
370699ff47SMichael Grosse        $QB->filters()->whereAnd("$datatable.latest = 1");
380699ff47SMichael Grosse
390699ff47SMichael Grosse        $col = $this->columns[0];
400699ff47SMichael Grosse        if($col->isMulti()) {
410699ff47SMichael Grosse            $multitable = "multi_{$col->getTable()}";
420699ff47SMichael Grosse            $MN = 'M' . $col->getColref();
430699ff47SMichael Grosse
440699ff47SMichael Grosse            $QB->addLeftJoin(
450699ff47SMichael Grosse                $datatable,
460699ff47SMichael Grosse                $multitable,
470699ff47SMichael Grosse                $MN,
480699ff47SMichael Grosse                "$datatable.pid = $MN.pid AND
490699ff47SMichael Grosse                     $datatable.rev = $MN.rev AND
500699ff47SMichael Grosse                     $MN.colref = {$col->getColref()}"
510699ff47SMichael Grosse            );
520699ff47SMichael Grosse
530699ff47SMichael Grosse            $col->getType()->select($QB, $MN, 'value', 'tag');
540699ff47SMichael Grosse            $colname = $MN . 'value';
550699ff47SMichael Grosse        } else {
560699ff47SMichael Grosse            $col->getType()->select($QB, $datatable, $col->getColName(), 'tag');
570699ff47SMichael Grosse            $colname = $datatable . '.' . $col->getColName();
580699ff47SMichael Grosse        }
590699ff47SMichael Grosse        $QB->addSelectStatement("COUNT($colname)", 'count');
600699ff47SMichael Grosse        $QB->addGroupByStatement('tag');
61aafac1c1SMichael Grosse        $QB->addOrderBy('count DESC');
620699ff47SMichael Grosse
630699ff47SMichael Grosse        return $QB->getSQL();
640699ff47SMichael Grosse    }
650699ff47SMichael Grosse
660699ff47SMichael Grosse    /**
670699ff47SMichael Grosse     * Execute this search and return the result
680699ff47SMichael Grosse     *
690699ff47SMichael Grosse     * The result is a two dimensional array of Value()s.
700699ff47SMichael Grosse     *
710699ff47SMichael Grosse     * This will always query for the full result (not using offset and limit) and then
720699ff47SMichael Grosse     * return the wanted range, setting the count (@see getCount) to the whole result number
730699ff47SMichael Grosse     *
740699ff47SMichael Grosse     * @return Value[][]
750699ff47SMichael Grosse     */
760699ff47SMichael Grosse    public function execute() {
770699ff47SMichael Grosse        list($sql, $opts) = $this->getSQL();
780699ff47SMichael Grosse
790699ff47SMichael Grosse        /** @var \PDOStatement $res */
800699ff47SMichael Grosse        $res = $this->sqlite->query($sql, $opts);
810699ff47SMichael Grosse        if($res === false) throw new StructException("SQL execution failed for\n\n$sql");
820699ff47SMichael Grosse
830699ff47SMichael Grosse        $this->result_pids = array();
840699ff47SMichael Grosse        $result = array();
850699ff47SMichael Grosse        $cursor = -1;
86*ae457e47SMichael Grosse
870699ff47SMichael Grosse        while($row = $res->fetch(\PDO::FETCH_ASSOC)) {
88*ae457e47SMichael Grosse            if (!empty($this->config['min']) && $this->config['min'] > $row['count']) {
89*ae457e47SMichael Grosse                break;
90*ae457e47SMichael Grosse            }
910699ff47SMichael Grosse            $cursor++;
920699ff47SMichael Grosse            if($cursor < $this->range_begin) continue;
930699ff47SMichael Grosse            if($this->range_end && $cursor >= $this->range_end) continue;
940699ff47SMichael Grosse
950699ff47SMichael Grosse            $row['tag'] = new Value($this->columns[0], $row['tag']);
960699ff47SMichael Grosse            $result[] = $row;
970699ff47SMichael Grosse        }
980699ff47SMichael Grosse
990699ff47SMichael Grosse        $this->sqlite->res_close($res);
1000699ff47SMichael Grosse        $this->count = $cursor + 1;
1010699ff47SMichael Grosse        return $result;
1020699ff47SMichael Grosse    }
1030699ff47SMichael Grosse}
104