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