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