Completed
Push — work-fleets ( ab0738...1c4183 )
by SuperNova.WS
05:52
created

DbSqlStatement::order()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 5
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 9
ccs 0
cts 5
cp 0
crap 6
rs 9.6666
1
<?php
2
3
//pdump(DBStaticUser::getMaxId());
0 ignored issues
show
Unused Code Comprehensibility introduced by
65% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
4
//pdump(DBStaticUser::getRecordById(67));
5
//pdump(DBStaticUser::filterIdListStringRepack('2,3,5,67'));
6
7
8
class DbSqlStatement {
9
10
  const SELECT = 'SELECT';
11
12
  protected static $allowedOperations = array(
13
    self::SELECT,
14
  );
15
16
  /**
17
   * @var db_mysql $db
18
   */
19
  protected $db;
20
21
  public $operation = '';
22
23
  public $table = '';
24
  public $alias = '';
25
26
  public $idField = '';
27
28
  /**
29
   * @var array
30
   */
31
  public $fields = array();
32
33
  public $where = array();
34
  public $group = array();
35
  public $order = array();
36
  /**
37
   * @var array
38
   *  [0] - row_count
39
   *  [1] - offset
40
   *    Used {LIMIT row_count [OFFSET offset]} syntax
41
   */
42
  // TODO - separate offset and row_count
43
  public $limit = array();
44
45
  public $fetchOne = false;
46
47
  /**
48
   * @param db_mysql|null $db
49
   * @param string        $className
50
   *
51
   * @return DbSqlStatement
52
   */
53 1
  public static function build($db = null, $className = '') {
54 1
    $result = new self($db);
55 1
    if (!empty($className) && is_string($className)) {
56 1
      $result->getParamsFromStaticClass($className);
57 1
    }
58
59 1
    return $result;
60
  }
61
62
  /**
63
   * DbSqlStatement constructor.
64
   *
65
   * @param db_mysql|null $db
66
   */
67 3
  public function __construct($db = null) {
68 3
    $this->db = (!empty($db) && $db instanceof db_mysql) || !class_exists('classSupernova', false) ? $db : classSupernova::$db;
69 3
  }
70
71
  /**
72
   * Resets statement
73
   *
74
   * @param bool $full
75
   *
76
   * @return $this
77
   */
78
  // TODO - UNITTEST
79 1
  protected function _reset($full = true) {
80 1
    if ($full) {
81 1
      $this->operation = '';
82 1
      $this->table = '';
83 1
      $this->alias = '';
84 1
      $this->idField = '';
85 1
    }
86
87 1
    $this->fields = array();
88 1
    $this->where = array();
89 1
    $this->group = array();
90 1
    $this->order = array();
91 1
    $this->limit = array();
92 1
    $this->fetchOne = false;
93
94 1
    return $this;
95
  }
96
97
  /**
98
   * @param string $fieldName
99
   *
100
   * @return $this
101
   */
102 1
  public function setIdField($fieldName) {
103 1
    $this->idField = $fieldName;
104
105 1
    return $this;
106
  }
107
108
  /**
109
   * @param string $alias
110
   *
111
   * @return $this
112
   */
113 1
  public function fromAlias($alias) {
114 1
    $this->alias = $alias;
115
116 1
    return $this;
117
  }
118
119
  /**
120
   * @param string $tableName
121
   * @param string $alias
122
   *
123
   * @return $this
124
   */
125 1
  public function from($tableName, $alias = '') {
126 1
    $this->table = $tableName;
127 1
    $this->fromAlias($alias);
128
129 1
    return $this;
130
  }
131
132
  /**
133
   * @param string $params
134
   *
135
   * @return $this
136
   */
137 2
  public function getParamsFromStaticClass($params) {
138 2
    if (is_string($params) && $params && class_exists($params)) {
139 2
      $this->from($params::$_table);
140 2
      $this->setIdField($params::$_idField);
141 2
    }
142
143 2
    return $this;
144
  }
145
146
147
  /**
148
   * @return self
149
   */
150 2
  public function select() {
151 2
    $this->_reset(false);
152 2
    $this->operation = DbSqlStatement::SELECT;
153 2
    $this->fields = array('*');
154
155 2
    return $this;
156
  }
157
158
  /**
159
   * @param array $fields
160
   *
161
   * @return $this
162
   */
163 1
  public function fields($fields = array()) {
164 1
    $this->fields = $fields;
165
166 1
    return $this;
167
  }
168
169
  /**
170
   * @param array $where
171
   * @param bool  $replace
172
   *
173
   * @return $this
174
   * @throws ExceptionDbSqlWhereNotAnArray
175
   */
176
  // TODO - fields should be escaped !!
177
  // TODO - $where should be validated and checked!
178 1
  public function where($where = array(), $replace = true) {
179 1
    if (!is_array($where)) {
180
      throw new ExceptionDbSqlWhereNotAnArray();
181
    }
182
183 1
    if ($replace) {
184 1
      $this->where = $where;
185 1
    } else {
186
      $this->where = array_merge($this->where, $where);
187
    }
188
189 1
    return $this;
190
  }
191
192
  /**
193
   * @param array $order
194
   *
195
   * @return $this
196
   * @throws ExceptionDbSqlWhereNotAnArray
197
   */
198
  // TODO - fields should be escaped !!
199
  // TODO - $where should be validated and checked!
200
  public function order($order = array()) {
201
    if (!is_array($order)) {
202
      // TODO - separate exception
203
      throw new ExceptionDbSqlWhereNotAnArray();
204
    }
205
    $this->order = $order;
206
207
    return $this;
208
  }
209
210
  /**
211
   * @return $this
212
   */
213
  public function fetchOne() {
214
    $this->fetchOne = true;
215
    $this->limit[0] = 1;
216
217
    return $this;
218
  }
219
220
  /**
221
   * @return string
222
   * @throws ExceptionDbOperationEmpty
223
   * @throws ExceptionDbOperationRestricted
224
   */
225 2
  public function __toString() {
226 2
    if (empty($this->operation)) {
227 1
      throw new ExceptionDbOperationEmpty();
228
    }
229
230 1
    if (!in_array($this->operation, self::$allowedOperations)) {
231 1
      throw new ExceptionDbOperationRestricted();
232
    }
233
234
    $result = '';
235
    $result .= $this->stringEscape($this->operation);
236
237
    $result .= ' ' . $this->selectFieldsToString($this->fields);
238
239
    $result .= ' FROM';
240
    $result .= ' `{{' . $this->stringEscape($this->table) . '}}`';
241
    $result .= !empty($this->alias) ? ' AS `' . $this->stringEscape($this->alias) . '`' : '';
242
243
    // TODO - fields should be escaped !!
244
    $result .= !empty($this->where) ? ' WHERE ' . implode(' AND ', $this->where) : '';
245
246
    // TODO - fields should be escaped !!
247
    $result .= !empty($this->group) ? ' GROUP BY ' . implode(',', $this->group) : '';
248
249
    // TODO - fields should be escaped !!
250
    $result .= !empty($this->order) ? ' ORDER BY ' . implode(',', $this->order) : '';
251
252
    // TODO - fields should be escaped !!
253
    // TODO - separate offset and row_count
254
    $result .= !empty($this->limit) ? ' LIMIT ' . implode(' OFFSET ', $this->limit) : '';
255
256
    // TODO - protect from double escape!
257
258
    return $result;
259
  }
260
261
  /**
262
   * @param array|mixed $fields
263
   *
264
   * @return string
265
   * @throws ExceptionDBFieldEmpty
266
   */
267 16
  protected function selectFieldsToString($fields) {
268 16
    $fields = HelperArray::makeArray($fields);
269
270 16
    $result = array();
271 16
    foreach ($fields as $fieldName) {
272 15
      $string = $this->processField($fieldName);
273 15
      if ($string !== '') {
274 13
        $result[] = $string;
275 13
      }
276 16
    }
277
278 16
    if (empty($result)) {
279 3
      throw new ExceptionDBFieldEmpty();
280
    }
281
282 13
    return implode(',', $result);
283
  }
284
285
  /**
286
   * @param mixed $fieldName
287
   *
288
   * @return string
289
   */
290 13
  protected function processField($fieldName) {
291 13
    if (is_bool($fieldName)) {
292 4
      $result = (string)intval($fieldName);
293 13
    } elseif (is_null($fieldName)) {
294 2
      $result = 'NULL';
295 11
    } elseif ($fieldName === '*') {
296 2
      $result = '*';
297 2
    } else {
298 9
      $result = $this->processFieldDefault($fieldName);
299
    }
300
301 13
    return $result;
302
  }
303
304
  /**
305
   * @param mixed $fieldName
306
   *
307
   * @return string
308
   */
309 9
  protected function processFieldDefault($fieldName) {
310 9
    $result = (string)$fieldName;
311
    if (
312
      $result != ''
313 9
      &&
314
      // Literals plays as they are - they do properly format by itself
315 8
      !($fieldName instanceof DbSqlLiteral)
316 9
      &&
317
      // Numeric need no escaping
318 7
      !is_numeric($fieldName)
319 9
    ) {
320
      // Other should be formatted
321 3
      $result = '`' . $this->stringEscape($result) . '`';
322 3
    }
323
324 9
    return $result;
325
  }
326
327
  /**
328
   * @param $string
329
   *
330
   * @return mixed|string
331
   */
332
  protected function stringEscape($string) {
333
    return
334
      method_exists($this->db, 'db_escape')
335
        ? $this->db->db_escape($string)
336
        : str_replace('`', '\`', addslashes($string));
337
  }
338
339
}
340