Completed
Push — work-fleets ( a5a64a...fb09a7 )
by SuperNova.WS
06:25
created

DbSqlStatement::selectFieldsToString()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 17
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 4

Importance

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