Passed
Push — main ( 99a7ee...701a87 )
by BRUNO
02:24
created

DatalayerTrait::lastId()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 7
Bugs 0 Features 0
Metric Value
cc 2
eloc 4
c 7
b 0
f 0
nc 2
nop 0
dl 0
loc 6
rs 10
1
<?php
2
namespace BMorais\Database;
3
4
/**
5
 * CLASS TRAIT DATALAYER
6
 * This class of execution methods in the database
7
 *
8
 * @author Bruno Morais <[email protected]>
9
 * @copyright MIT, bmorais.com
10
 * @package bmorais\database
11
 * @subpackage class
12
 * @access private
13
 */
14
use PDO;
15
use PDOException;
16
use PDOStatement;
17
use stdClass;
18
19
trait DatalayerTrait
20
{
21
    /** @var PDO|null
22
     * @deprecated
23
     * */
24
    protected $instance = null;
25
26
    /** @var string
27
     *  @deprecated
28
     */
29
    protected string $fields;
30
31
    /** @var PDOStatement|null
32
     *   @deprecated */
33
    protected $prepare = null;
34
35
    /** @var string
36
     *  @deprecated
37
     */
38
    protected $database = CONFIG_DATA_LAYER["dbname"];
39
40
    /** @var string
41
     *  @deprecated
42
     */
43
    protected $classModel;
44
45
    /** @var string
46
     * @deprecated
47
     */
48
    protected $tableName;
49
50
    /** @var string */
51
    private $tableAlias;
52
53
    /** @var array
54
     */
55
    private array $resultArray = [];
56
57
    /** @var string */
58
    private $logSQL;
59
60
    /** @var PDOException */
61
    private $error;
62
63
    /** @var string */
64
    private string $query = "";
65
66
    /** @var array */
67
    private array $params = [];
68
69
70
    /** @return PDO|false */
71
    private function getConnect()
72
    {
73
        try {
74
            if (strpos($_SERVER['SERVER_NAME'], mb_strtolower(CONFIG_DATA_LAYER["homologation"])) && !strpos($this->getDatabase(), ucfirst(CONFIG_DATA_LAYER["homologation"]))) {
75
                $database = $this->getDatabase().ucfirst(CONFIG_DATA_LAYER["homologation"] ?? "");
76
                $this->setDatabase($database);
77
            }
78
79
            if (empty($this->instance)) {
0 ignored issues
show
Deprecated Code introduced by
The property BMorais\Database\DatalayerTrait::$instance has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

79
            if (empty(/** @scrutinizer ignore-deprecated */ $this->instance)) {
Loading history...
80
                $this->instance = new PDO(
0 ignored issues
show
Deprecated Code introduced by
The property BMorais\Database\DatalayerTrait::$instance has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

80
                /** @scrutinizer ignore-deprecated */ $this->instance = new PDO(
Loading history...
81
                    CONFIG_DATA_LAYER['driver'] . ':host=' . CONFIG_DATA_LAYER['host'] . ';dbname=' . $this->getDatabase() . ';port=' . CONFIG_DATA_LAYER['port'],
82
                    CONFIG_DATA_LAYER['username'],
83
                    CONFIG_DATA_LAYER['passwd'],
84
                    CONFIG_DATA_LAYER['options']
85
                );
86
            }
87
88
            return $this->instance;
0 ignored issues
show
Deprecated Code introduced by
The property BMorais\Database\DatalayerTrait::$instance has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

88
            return /** @scrutinizer ignore-deprecated */ $this->instance;
Loading history...
89
        } catch (PDOException $e) {
90
            $this->setError($e);
91
        }
92
93
    }
94
95
    /**
96
     * @param ?PDO $pdo
97
     * @return Crud
98
     *
99
     */
100
    protected function setInstance(?PDO $pdo): self
101
    {
102
        $this->instance = $pdo;
0 ignored issues
show
Deprecated Code introduced by
The property BMorais\Database\DatalayerTrait::$instance has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

102
        /** @scrutinizer ignore-deprecated */ $this->instance = $pdo;
Loading history...
103
        return $this;
104
    }
105
106
    protected function getInstance(): PDO
107
    {
108
        return $this->getConnect();
109
    }
110
111
    /**
112
     * @param string $database
113
     * @return $this
114
     */
115
    protected function setDatabase(string $database): self
116
    {
117
        if (strpos($_SERVER['SERVER_NAME'], mb_strtolower(CONFIG_DATA_LAYER["homologation"])) && !strpos($database, ucfirst(CONFIG_DATA_LAYER["homologation"]))) {
118
            $database = $database.ucfirst(CONFIG_DATA_LAYER["homologation"] ?? "");
119
            $this->database = $database;
0 ignored issues
show
Deprecated Code introduced by
The property BMorais\Database\DatalayerTrait::$database has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

119
            /** @scrutinizer ignore-deprecated */ $this->database = $database;
Loading history...
120
        } else {
121
            $this->database = $database;
0 ignored issues
show
Deprecated Code introduced by
The property BMorais\Database\DatalayerTrait::$database has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

121
            /** @scrutinizer ignore-deprecated */ $this->database = $database;
Loading history...
122
        }
123
124
        if (!empty($this->instance)){
0 ignored issues
show
Deprecated Code introduced by
The property BMorais\Database\DatalayerTrait::$instance has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

124
        if (!empty(/** @scrutinizer ignore-deprecated */ $this->instance)){
Loading history...
125
            $this->executeSQL("USE {$this->getDatabase()}");
126
        }
127
128
        return $this;
129
    }
130
131
    /**
132
     * @return string
133
     */
134
    protected function getDatabase(): string
135
    {
136
        return $this->database ?? "";
0 ignored issues
show
Deprecated Code introduced by
The property BMorais\Database\DatalayerTrait::$database has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

136
        return /** @scrutinizer ignore-deprecated */ $this->database ?? "";
Loading history...
137
    }
138
139
    /**
140
     * @param string $fields
141
     * @return Crud
142
     */
143
    protected function setFields(string $fields): self
144
    {
145
        $this->fields = $fields;
0 ignored issues
show
Deprecated Code introduced by
The property BMorais\Database\DatalayerTrait::$fields has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

145
        /** @scrutinizer ignore-deprecated */ $this->fields = $fields;
Loading history...
146
        return $this;
147
    }
148
149
    /**
150
     * @return string
151
     */
152
    protected function getFields():string
153
    {
154
        return $this->fields;
0 ignored issues
show
Deprecated Code introduced by
The property BMorais\Database\DatalayerTrait::$fields has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

154
        return /** @scrutinizer ignore-deprecated */ $this->fields;
Loading history...
155
    }
156
157
    /**
158
        * @param string $tableName
159
        * @param string $tableAlias
160
        * @return CrudBuilder|Crud|DatalayerTrait
161
     */
162
    protected function setTable(string $tableName, string $tableAlias = ""): self
163
    {
164
        if (!empty($tableAlias))
165
            $this->tableAlias = $tableAlias;
166
        $this->tableName = $tableName;
0 ignored issues
show
Deprecated Code introduced by
The property BMorais\Database\DatalayerTrait::$tableName has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

166
        /** @scrutinizer ignore-deprecated */ $this->tableName = $tableName;
Loading history...
167
        return $this;
168
    }
169
170
    /**
171
     * @return string
172
     */
173
    protected function getTable(): string
174
    {
175
        return $this->tableName ?? "";
0 ignored issues
show
Deprecated Code introduced by
The property BMorais\Database\DatalayerTrait::$tableName has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

175
        return /** @scrutinizer ignore-deprecated */ $this->tableName ?? "";
Loading history...
176
    }
177
178
    protected function getTableAlias(): string
179
    {
180
        return $this->tableAlias ?? "";
181
    }
182
183
    /**
184
     * @param string $classModel
185
     * @return Crud
186
     */
187
    protected function setClassModel(string $classModel): self
188
    {
189
        $this->classModel = $classModel;
0 ignored issues
show
Deprecated Code introduced by
The property BMorais\Database\DatalayerTrait::$classModel has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

189
        /** @scrutinizer ignore-deprecated */ $this->classModel = $classModel;
Loading history...
190
        return $this;
191
    }
192
193
    protected function getClassModel(): string
194
    {
195
        return $this->classModel;
0 ignored issues
show
Deprecated Code introduced by
The property BMorais\Database\DatalayerTrait::$classModel has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

195
        return /** @scrutinizer ignore-deprecated */ $this->classModel;
Loading history...
196
    }
197
198
    /**
199
     * @param string $classModel
200
     * @return Crud
201
     */
202
    protected function setPrepare(PDOStatement $prepare): self
203
    {
204
        $this->prepare = $prepare;
0 ignored issues
show
Deprecated Code introduced by
The property BMorais\Database\DatalayerTrait::$prepare has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

204
        /** @scrutinizer ignore-deprecated */ $this->prepare = $prepare;
Loading history...
205
        return $this;
206
    }
207
208
    protected function getPrepare(): PDOStatement
209
    {
210
        return $this->prepare;
0 ignored issues
show
Deprecated Code introduced by
The property BMorais\Database\DatalayerTrait::$prepare has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

210
        return /** @scrutinizer ignore-deprecated */ $this->prepare;
Loading history...
Bug Best Practice introduced by
The expression return $this->prepare could return the type null which is incompatible with the type-hinted return PDOStatement. Consider adding an additional type-check to rule them out.
Loading history...
211
    }
212
213
    protected function getResult(): array
214
    {
215
       return $this->resultArray;
216
    }
217
218
    protected function setResult(array $array): self
219
    {
220
        $this->resultArray = $array;
221
        return $this;
222
    }
223
224
    /**
225
        * @param string $query
226
        * @param array|null $params
227
        * @return PDOStatement|void
228
     */
229
    protected function executeSQL(string $query, ?array $params = null)
230
    {
231
        try {
232
            $this->setPrepare($this->getInstance()->prepare($query));
233
            $this->setSQL($query, $params);
234
            $this->getPrepare()->execute($params);
235
            return $this->getPrepare();
236
        } catch (PDOException $e) {
237
            $this->setError($e);
238
        }
239
    }
240
241
    /**
242
     * @param $prepare
243
     * @return int|false
244
     */
245
    protected function count(PDOStatement $prepare = null): ?int
246
    {
247
        try {
248
            $prepare = empty($prepare) ? $this->getPrepare() : $prepare;
249
            return $prepare->rowCount();
250
        } catch (PDOException $e) {
251
            $this->setError($e);}
252
    }
253
254
    /**
255
    * @param PDOStatement|null $prepare
256
    * @return array|null
257
     */
258
    protected function fetchArrayAssoc(PDOStatement $prepare = null): ?array
259
    {
260
        try {
261
            $prepare = empty($prepare) ? $this->getPrepare() : $prepare;
262
            $dados = $prepare->fetchAll(PDO::FETCH_ASSOC);
263
            $this->setResult($dados);
264
            return $dados;
265
        } catch (PDOException $e) {
266
            $this->setError($e);
267
        }
268
    }
269
270
    /**
271
     * @param $prepare
272
     * @return array|false
273
     */
274
    protected function fetchArrayObj(PDOStatement $prepare = null): ?array
275
    {
276
        try {
277
            $prepare = empty($prepare) ? $this->getPrepare() : $prepare;
278
            $dados = $prepare->fetchAll(PDO::FETCH_OBJ);
279
            $this->setResult($dados);
280
            return $dados;
281
        } catch (PDOException $e) {
282
            $this->setError($e);
283
        }
284
    }
285
286
    /**
287
     * @param $prepare
288
     * @param String|null $classModel
289
     * @return array|false
290
     */
291
    protected function fetchArrayClass(PDOStatement $prepare = null, string $classModel = null): ?array
292
    {
293
        try {
294
            $prepare = empty($prepare) ? $this->getPrepare() : $prepare;
295
            $classModel = empty($classModel) ? $this->getClassModel() : $classModel;
296
            $dados = $prepare->fetchAll(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, CONFIG_DATA_LAYER["directory_models"] . $classModel);
297
            $this->setResult($dados);
298
            return $dados;
299
        } catch (PDOException $e) {
300
            $this->setError($e);
301
        }
302
    }
303
304
    /**
305
     * @param $prepare
306
     * @return array|false
307
     */
308
    protected function fetchOneAssoc(PDOStatement $prepare = null): ?array
309
    {
310
        try {
311
            $prepare = empty($prepare) ? $this->getPrepare() : $prepare;
312
            return $prepare->fetch(PDO::FETCH_ASSOC);
313
        } catch (PDOException $e) {
314
            $this->setError($e);
315
        }
316
    }
317
318
    /**
319
    * @param PDOStatement|null $prepare
320
    * @return stdClass|null
321
     */
322
    protected function fetchOneObj(PDOStatement $prepare = null): ?stdClass
323
    {
324
        try {
325
            $prepare = empty($prepare) ? $this->getPrepare() : $prepare;
326
            return $prepare->fetch(PDO::FETCH_OBJ);
327
        } catch (PDOException $e) {
328
            $this->setError($e);
329
        }
330
    }
331
332
    /**
333
     * @param $prepare
334
     * @param String|null $class
335
     * @return array|false
336
     */
337
    protected function fetchOneClass(PDOStatement $prepare = null, string $class = null): ?object
338
    {
339
        try {
340
            $prepare = empty($prepare) ? $this->getPrepare() : $prepare;
341
            $class = empty($class) ? $this->getClassModel() : $class;
342
            return $prepare->fetchObject(CONFIG_DATA_LAYER["directory_models"] . $class);
343
        } catch (PDOException $e) {
344
            $this->setError($e);
345
        }
346
    }
347
348
    /**
349
     * @return bool
350
     */
351
    protected function beginTrasaction(): ?bool
352
    {
353
        try {
354
            $this->getInstance()->beginTransaction();
355
            return true;
356
        } catch (PDOException $e) {
357
            $this->setError($e);
358
        }
359
360
    }
361
362
    /**
363
     * @return bool|null
364
     */
365
    protected function commitTransaction(): ?bool
366
    {
367
        try {
368
            $this->getInstance()->commit();
369
            return true;
370
        } catch (PDOException $e) {
371
            $this->setError($e);
372
        }
373
    }
374
375
    /**
376
     * @return bool|null
377
     *
378
     */
379
    protected function rollBackTransaction(): ?bool
380
    {
381
382
        try {
383
            $this->getInstance()->rollBack();
384
            return true;
385
        } catch (PDOException $e) {
386
            $this->setError($e);
387
        }
388
    }
389
390
    /**
391
     *  @return string|null
392
     *  */
393
    private function lastId(): ?string
394
    {
395
        try {
396
            return $this->getInstance()->lastInsertId();
397
        } catch (PDOException $e) {
398
            $this->setError($e);
399
        }
400
    }
401
402
    /**
403
     * @param $sql_string
404
     * @param array|null $params
405
     * @return void
406
     */
407
    private function setSQL($sql_string, ?array $params = null)
408
    {
409
        try {
410
            if (!empty($params)) {
411
                $indexed = $params == array_values($params);
412
                foreach ($params as $k => $v) {
413
                    if (is_object($v)) {
414
                        if ($v instanceof \DateTime) {
415
                            $v = $v->format('Y-m-d H:i:s');
416
                        } else {
417
                            continue;
418
                        }
419
                    } elseif (is_string($v)) {
420
                        $v = "'$v'";
421
                    } elseif ($v === null) {
422
                        $v = 'NULL';
423
                    } elseif (is_array($v)) {
424
                        $v = implode(',', $v);
425
                    }
426
427
                    if ($indexed) {
428
                        $sql_string = preg_replace('/\?/', $v, $sql_string, 1);
429
                    } else {
430
                        if ($k[0] != ':') {
431
                            $k = ':' . $k;
432
                        } //add leading colon if it was left out
433
                        $sql_string = str_replace($k, $v, $sql_string);
434
                    }
435
                }
436
            }
437
            $this->logSQL = $sql_string;
438
        } catch (PDOException $e) {
439
            $this->setError($e);
440
        }
441
    }
442
443
    /**
444
     * @return string|null
445
     */
446
    protected function getSQL(): ?string
447
    {
448
        try {
449
            return $this->logSQL ?? "";
450
        } catch (\PDOException $e) {
0 ignored issues
show
Unused Code introduced by
catch (\PDOException $e) is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
451
            $this->setError($e);
452
        }
453
    }
454
455
    /**
456
     * @param PDOException $e
457
     * @return void
458
     */
459
    private function setError(PDOException $e)
460
    {
461
        $this->error = $e;
462
        throw new PDOException("{$e->getMessage()}<br/><b>SQL:</b> {$this->getSQL()}");
463
464
    }
465
}
466