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