Passed
Push — main ( b6b23f...e918fc )
by BRUNO
02:34
created

DatalayerTrait::setInstance()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 1
eloc 2
c 2
b 0
f 0
nc 1
nop 1
dl 0
loc 4
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 USE $this->setClassModel("NAME");
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 string $database = CONFIG_DATA_LAYER["dbname"];
39
40
    /** @var string
41
     *  @deprecated USE $this->setInstance(PDO);
42
     */
43
    protected string $classModel;
44
45
    /** @var string
46
     * @deprecated USE $this->setTableName("name");
47
     */
48
    protected string $tableName;
49
50
    /** @var string */
51
    private string $tableAlias;
52
53
    /** @var array
54
     */
55
    private array $data = [];
56
57
    /** @var string */
58
    private string $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: USE $this->setClassModel("NAME"); ( 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)) {

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
80
                $this->instance = new PDO(
0 ignored issues
show
Deprecated Code introduced by
The property BMorais\Database\DatalayerTrait::$instance has been deprecated: USE $this->setClassModel("NAME"); ( 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(

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

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: USE $this->setClassModel("NAME"); ( 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;

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

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: USE $this->setClassModel("NAME"); ( 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;

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

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: USE $this->setClassModel("NAME"); ( 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)){

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

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 setTableName(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: USE $this->setTableName("name"); ( 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;

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
167
        return $this;
168
    }
169
170
    /**
171
     * @return string
172
     */
173
    protected function getTableName(): string
174
    {
175
        return $this->tableName ?? "";
0 ignored issues
show
Deprecated Code introduced by
The property BMorais\Database\DatalayerTrait::$tableName has been deprecated: USE $this->setTableName("name"); ( 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 ?? "";

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

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: USE $this->setInstance(PDO); ( 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;

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

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: USE $this->setInstance(PDO); ( 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;

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

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
    /**
214
     * @param $params
215
     * @return self
216
     */
217
    protected function setParams($params): self
218
    {
219
        $this->params = array_merge($this->params, $params);
220
        return $this;
221
    }
222
223
    /**
224
     * @param $params
225
     * @return array
226
     */
227
    protected function getParams(): array
228
    {
229
        return $this->params;
230
    }
231
232
    protected function getData(): array
233
    {
234
       return $this->data;
235
    }
236
237
    protected function setData(array $array): self
238
    {
239
        $this->data = $array;
240
        return $this;
241
    }
242
    public  function getQuery(): string
243
    {
244
        return $this->query;
245
    }
246
    public  function setQuery(string $query): self
247
    {
248
        $this->query = $query;
249
        return $this;
250
    }
251
252
    /**
253
        * @param string $query
254
        * @param array|null $params
255
        * @return PDOStatement|void
256
     */
257
    protected function executeSQL(string $query, ?array $params = null)
258
    {
259
        try {
260
            $this->setPrepare($this->getInstance()->prepare($query));
261
            $this->setSQL($query, $params);
262
            $this->getPrepare()->execute($params);
263
            return $this->getPrepare();
264
        } catch (PDOException $e) {
265
            $this->setError($e);
266
        }
267
    }
268
269
    /**
270
     * @param $prepare
271
     * @return int|false
272
     */
273
    protected function rowCount(PDOStatement $prepare = null): ?int
274
    {
275
        try {
276
            $prepare = empty($prepare) ? $this->getPrepare() : $prepare;
277
            return $prepare->rowCount();
278
        } catch (PDOException $e) {
279
            $this->setError($e);}
280
    }
281
282
    /**
283
    * @param PDOStatement|null $prepare
284
    * @return array|null
285
     */
286
    protected function fetchArrayAssoc(PDOStatement $prepare = null): ?array
287
    {
288
        try {
289
            $prepare = empty($prepare) ? $this->getPrepare() : $prepare;
290
            $dados = $prepare->fetchAll(PDO::FETCH_ASSOC);
291
            $this->setData($dados);
292
            return $dados;
293
        } catch (PDOException $e) {
294
            $this->setError($e);
295
        }
296
    }
297
298
    /**
299
     * @param $prepare
300
     * @return array|false
301
     */
302
    protected function fetchArrayObj(PDOStatement $prepare = null): ?array
303
    {
304
        try {
305
            $prepare = empty($prepare) ? $this->getPrepare() : $prepare;
306
            $dados = $prepare->fetchAll(PDO::FETCH_OBJ);
307
            $this->setData($dados);
308
            return $dados;
309
        } catch (PDOException $e) {
310
            $this->setError($e);
311
        }
312
    }
313
314
    /**
315
     * @param $prepare
316
     * @param String|null $classModel
317
     * @return array|false
318
     */
319
    protected function fetchArrayClass(PDOStatement $prepare = null, string $classModel = null): ?array
320
    {
321
        try {
322
            $prepare = empty($prepare) ? $this->getPrepare() : $prepare;
323
            $classModel = empty($classModel) ? $this->getClassModel() : $classModel;
324
            $dados = $prepare->fetchAll(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, CONFIG_DATA_LAYER["directory_models"] . $classModel);
325
            $this->setData($dados);
326
            return $dados;
327
        } catch (PDOException $e) {
328
            $this->setError($e);
329
        }
330
    }
331
332
    /**
333
     * @param $prepare
334
     * @return array|false
335
     */
336
    protected function fetchOneAssoc(PDOStatement $prepare = null): ?array
337
    {
338
        try {
339
            $prepare = empty($prepare) ? $this->getPrepare() : $prepare;
340
            return $prepare->fetch(PDO::FETCH_ASSOC);
341
        } catch (PDOException $e) {
342
            $this->setError($e);
343
        }
344
    }
345
346
    /**
347
    * @param PDOStatement|null $prepare
348
    * @return stdClass|null
349
     */
350
    protected function fetchOneObj(PDOStatement $prepare = null): ?stdClass
351
    {
352
        try {
353
            $prepare = empty($prepare) ? $this->getPrepare() : $prepare;
354
            return $prepare->fetch(PDO::FETCH_OBJ);
355
        } catch (PDOException $e) {
356
            $this->setError($e);
357
        }
358
    }
359
360
    /**
361
     * @param $prepare
362
     * @param String|null $class
363
     * @return array|false
364
     */
365
    protected function fetchOneClass(PDOStatement $prepare = null, string $class = null): ?object
366
    {
367
        try {
368
            $prepare = empty($prepare) ? $this->getPrepare() : $prepare;
369
            $class = empty($class) ? $this->getClassModel() : $class;
370
            return $prepare->fetchObject(CONFIG_DATA_LAYER["directory_models"] . $class);
371
        } catch (PDOException $e) {
372
            $this->setError($e);
373
        }
374
    }
375
376
    /**
377
     * @return bool
378
     */
379
    protected function beginTrasaction(): ?bool
380
    {
381
        try {
382
            $this->getInstance()->beginTransaction();
383
            return true;
384
        } catch (PDOException $e) {
385
            $this->setError($e);
386
        }
387
388
    }
389
390
    /**
391
     * @return bool|null
392
     */
393
    protected function commitTransaction(): ?bool
394
    {
395
        try {
396
            $this->getInstance()->commit();
397
            return true;
398
        } catch (PDOException $e) {
399
            $this->setError($e);
400
        }
401
    }
402
403
    /**
404
     * @return bool|null
405
     *
406
     */
407
    protected function rollBackTransaction(): ?bool
408
    {
409
410
        try {
411
            $this->getInstance()->rollBack();
412
            return true;
413
        } catch (PDOException $e) {
414
            $this->setError($e);
415
        }
416
    }
417
418
    /**
419
     *  @return string|null
420
     *  */
421
    private function lastId(): ?string
422
    {
423
        try {
424
            return $this->getInstance()->lastInsertId();
425
        } catch (PDOException $e) {
426
            $this->setError($e);
427
        }
428
    }
429
430
    /**
431
     * @param $sql_string
432
     * @param array|null $params
433
     * @return void
434
     */
435
    private function setSQL($sql_string, ?array $params = null)
436
    {
437
        try {
438
            if (!empty($params)) {
439
                $indexed = $params == array_values($params);
440
                foreach ($params as $k => $v) {
441
                    if (is_object($v)) {
442
                        if ($v instanceof \DateTime) {
443
                            $v = $v->format('Y-m-d H:i:s');
444
                        } else {
445
                            continue;
446
                        }
447
                    } elseif (is_string($v)) {
448
                        $v = "'$v'";
449
                    } elseif ($v === null) {
450
                        $v = 'NULL';
451
                    } elseif (is_array($v)) {
452
                        $v = implode(',', $v);
453
                    }
454
455
                    if ($indexed) {
456
                        $sql_string = preg_replace('/\?/', $v, $sql_string, 1);
457
                    } else {
458
                        if ($k[0] != ':') {
459
                            $k = ':' . $k;
460
                        } //add leading colon if it was left out
461
                        $sql_string = str_replace($k, $v, $sql_string);
462
                    }
463
                }
464
            }
465
            $this->logSQL = $sql_string;
466
        } catch (PDOException $e) {
467
            $this->setError($e);
468
        }
469
    }
470
471
    /**
472
     * @return string|null
473
     */
474
    protected function getSQL(): ?string
475
    {
476
        try {
477
            return $this->logSQL ?? "";
478
        } 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...
479
            $this->setError($e);
480
        }
481
    }
482
483
    /**
484
     * @param PDOException $e
485
     * @return void
486
     */
487
    protected function setError(PDOException $e)
488
    {
489
        $this->error = $e;
490
        throw new PDOException("{$e->getMessage()} ###### SQL: {$this->getSQL()}");
491
492
    }
493
}
494