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