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