xref: /plugin/struct/meta/QueryBuilderWhere.php (revision af993d55de4e0a953dd341ba1012e1447afbac9b)
1<?php
2
3namespace dokuwiki\plugin\struct\meta;
4
5/**
6 * Class QueryWhere
7 * @package dokuwiki\plugin\struct\meta
8 */
9class QueryBuilderWhere {
10
11    /** @var  QueryBuilderWhere[]|string */
12    protected $statement;
13    /** @var string */
14    protected $type = 'AND';
15    /** @var QueryBuilder */
16    protected $QB;
17
18    /**
19     * Create a new WHERE clause
20     *
21     * @param string $type The type of the statement, either 'AND' or 'OR'
22     * @param null|string $statement The statement or null if this should hold sub statments
23     */
24    public function __construct(QueryBuilder $QB, $type = 'AND', $statement = null) {
25        $this->QB = $QB;
26        $this->type = $type;
27        if($statement === null) {
28            $this->statement = array();
29        } else {
30            $this->statement = $statement;
31        }
32    }
33
34    /**
35     * Adds another AND clause
36     *
37     * @param string $statement
38     * @return $this
39     */
40    public function whereAnd($statement) {
41        return $this->where('AND', $statement);
42    }
43
44    /**
45     * Adds another OR clause
46     *
47     * @param $statement
48     * @return $this
49     */
50    public function whereOr($statement) {
51        return $this->where('OR', $statement);
52    }
53
54    /**
55     * Add a new AND sub clause on which more statements can be added
56     *
57     * @return QueryBuilderWhere
58     */
59    public function whereSubAnd() {
60        return $this->where('AND', null);
61    }
62
63    /**
64     * Add a new OR sub clause on which more statements can be added
65     *
66     * @return QueryBuilderWhere
67     */
68    public function whereSubOr() {
69        return $this->where('OR', null);
70    }
71
72    /**
73     * Adds another statement to this sub clause
74     *
75     * @param string $op either AND or OR
76     * @param null|string $statement null creates a new sub clause
77     * @return $this|QueryBuilderWhere
78     * @throws StructException when this is not a sub clause
79     */
80    public function where($op = 'AND', $statement = null) {
81        if(!is_array($this->statement)) {
82            throw new StructException('This WHERE is not a sub clause and can not have additional clauses');
83        }
84        if($op != 'AND' && $op != 'OR') {
85            throw new StructException('Bad logical operator');
86        }
87        $where = new QueryBuilderWhere($this->QB, $op, $statement);
88        $this->statement[] = $where;
89
90        if($statement) {
91            return $this;
92        } else {
93            return $where;
94        }
95    }
96
97    /**
98     * @return QueryBuilder
99     */
100    public function getQB() {
101        return $this->QB;
102    }
103
104    /**
105     * @param bool $first is this the first where statement? Then the type is ignored
106     * @return string
107     */
108    public function toSQL($first = true) {
109        if(!$this->statement) return '';
110
111        $sql = ' ';
112        if(!$first) $sql .= $this->type . ' ';
113
114        if(is_array($this->statement)) {
115            $first = true;
116            $sql .= '(';
117            foreach($this->statement as $where) {
118                $sql .= $where->toSQL($first);
119                $first = false;
120            }
121            $sql .= ' )';
122        } else {
123            $sql .= $this->statement;
124        }
125
126        return $sql;
127    }
128}
129