Database::delete()   A
last analyzed

Complexity

Conditions 3
Paths 4

Size

Total Lines 16

Duplication

Lines 16
Ratio 100 %

Importance

Changes 0
Metric Value
cc 3
nc 4
nop 1
dl 16
loc 16
rs 9.7333
c 0
b 0
f 0
1
<?php
2
3
namespace System;
4
5
use PDO;
6
use PDOException;
7
use Exception;
8
9
class Database
10
{
11
    private $app;
12
13
    private static $connection;
14
15
    private $table;
16
17
    private $rows;
18
19
    private $lastId;
20
21
    private $data = [];
22
23
    private $bindings = [];
24
25
    private $selects = [];
26
27
    private $joins = [];
28
29
    private $wheres = [];
30
31
    private $havings = [];
32
33
    private $orderBy = [];
34
35
    private $limit;
36
37
    private $offset;
38
39
    private $groupBy = [];
40
41
    public function __construct(Application $app)
42
    {
43
        $this->app = $app;
44
45
        if (!$this->isConnected()) {
46
            $this->connect();
47
        }
48
    }
49
50
    private function isConnected()
51
    {
52
        return self::$connection instanceof PDO;
53
    }
54
55
    private function connect()
56
    {
57
        try {
58
            self::$connection = new PDO(
59
                $_ENV['DB_CONNECTION'] . ':host=' .
60
                    $_ENV['DB_HOST'] . ';dbname=' .
61
                    $_ENV['DB_DATABASE'],
62
                $_ENV['DB_USERNAME'],
63
                $_ENV['DB_PASSWORD']
64
            );
65
66
            self::$connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
67
68
            self::$connection->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
69
70
            self::$connection->exec('SET NAMES utf8');
71
        } catch (PDOException $e) {
72
            throw new Exception($e->getMessage());
73
        }
74
    }
75
76
    public function connection()
77
    {
78
        return self::$connection;
79
    }
80
81
    public function table($table)
82
    {
83
        $this->table = $table;
84
85
        return $this;
86
    }
87
88
    public function select(...$select)
89
    {
90
        $this->selects = array_merge($this->selects, $select);
91
92
        return $this;
93
    }
94
95
    public function join()
96
    {
97
        $args = func_get_args()[0];
98
        $sql = null;
99
100
        foreach ($args as $join) {
101
            $sql[] = $join[0] . ' ON ' . $this->table . '.' . $join[1] . ' = ' . $join[0] . '.' . $join[2];
102
        }
103
104
        $this->joins = $sql;
0 ignored issues
show
Documentation Bug introduced by
It seems like $sql of type null is incompatible with the declared type array of property $joins.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
105
106
        return $this;
107
    }
108
109
    public function where(...$bindings)
110
    {
111
        $sql = array_shift($bindings);
112
113
        if (is_array($bindings[0])) {
114
            $bindings = $bindings[0];
115
        }
116
117
        $this->addToBindings($bindings);
118
119
        $this->wheres[] = $sql;
120
121
        return $this;
122
    }
123
124
    public function having()
125
    {
126
        $bindings = func_get_args();
127
128
        $sql = array_shift($bindings);
129
130
        $this->addToBindings($bindings);
131
132
        $this->havings[] = $sql;
133
134
        return $this;
135
    }
136
137
    public function groupBy(...$arguments)
138
    {
139
        $this->groupBy = $arguments;
140
141
        return $this;
142
    }
143
144
    public function limit($limit, $offset = 0)
145
    {
146
        $this->limit = $limit;
147
148
        $this->offset = $offset;
149
150
        return $this;
151
    }
152
153
    public function rows()
154
    {
155
        return $this->rows;
156
    }
157
158
    public function orderBy($orderBy, $sort = 'ASC')
159
    {
160
        $this->orderBy = [$orderBy, $sort];
161
162
        return $this;
163
    }
164
165 View Code Duplication
    public function fetch($table = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
166
    {
167
        if ($table) {
168
            $this->table($table);
169
        }
170
171
        $sql = $this->fetchStatment();
172
173
        $sql = $this->fetchStatmentExtra($sql);
174
175
        $query = $this->query($sql, $this->bindings);
176
177
        $result = $query->fetch();
178
179
        $this->rows = $query->rowCount();
180
181
        return $result;
182
    }
183
184 View Code Duplication
    public function fetchAll($table = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
185
    {
186
        if ($table) {
187
            $this->table($table);
188
        }
189
190
        $sql = $this->fetchStatment();
191
192
        $sql = $this->fetchStatmentExtra($sql);
193
194
        $query = $this->query($sql, $this->bindings);
195
196
        $results = $query->fetchall();
197
198
        $this->rows = $query->rowCount();
199
200
        return $results;
201
    }
202
203
    private function fetchStatment()
204
    {
205
        $sql = 'SELECT ';
206
        $sql .= $this->selects ? implode(', ', $this->selects) : '*';
207
        $sql .= ' FROM ' . $this->table . ' ';
208
209
        if (!empty($this->joins)) {
210
            foreach ($this->joins as $join) {
211
                $sql .= 'LEFT JOIN ' . $join . ' ';
212
            }
213
        }
214
215
        if (!empty($this->wheres)) {
216
            $sql .= ' WHERE ' . implode(' ', $this->wheres);
217
        }
218
219
        return $sql;
220
    }
221
222
    private function fetchStatmentExtra($sql)
223
    {
224
        if (!empty($this->havings)) {
225
            $sql .= ' HAVING ' . implode(' ', $this->havings) . ' ';
226
        }
227
228
        if (!empty($this->orderBy)) {
229
            $sql .= ' ORDER BY ' . implode(' ', $this->orderBy);
230
        }
231
232
        if ($this->limit) {
233
            $sql .= ' LIMIT ' . $this->limit;
234
        }
235
236
        if ($this->offset) {
237
            $sql .= ' OFFSET ' . $this->offset;
238
        }
239
240
        if (!empty($this->groupBy)) {
241
            $sql .= ' GROUP BY ' . implode(' ', $this->groupBy);
242
        }
243
244
        return $sql;
245
    }
246
247
    public function lastId()
248
    {
249
        return $this->lastId;
250
    }
251
252
    public function from($table)
253
    {
254
        return $this->table($table);
255
    }
256
257
    public function data($key, $value = null)
258
    {
259
        if (is_array($key)) {
260
            $this->data = array_merge($this->data, $key);
261
262
            $this->addToBindings($key);
263
        } else {
264
            $this->data[$key] = $value;
265
266
            $this->addToBindings($value);
267
        }
268
269
        return $this;
270
    }
271
272
    public function insert($table = null)
273
    {
274
        if ($table) {
275
            $this->table($table);
276
        }
277
278
        $sql = 'INSERT INTO ' . $this->table . ' SET ';
279
        $sql .= $this->setField();
280
281
        $this->query($sql, $this->bindings);
282
283
        $this->lastId = $this->connection()->lastInsertId();
284
285
        return $this;
286
    }
287
288 View Code Duplication
    public function update($table = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
289
    {
290
        if ($table) {
291
            $this->table($table);
292
        }
293
294
        $sql = 'UPDATE ' . $this->table . ' SET ';
295
        $sql .= $this->setField();
296
297
        if (!empty($this->wheres)) {
298
            $sql .= ' WHERE ' . implode('', $this->wheres);
299
        }
300
301
        $this->query($sql, $this->bindings);
302
303
        return $this;
304
    }
305
306 View Code Duplication
    public function delete($table = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
307
    {
308
        if ($table) {
309
            $this->table($table);
310
        }
311
312
        $sql = 'DELETE FROM ' . $this->table . ' ';
313
314
        if (!empty($this->wheres)) {
315
            $sql .= ' WHERE ' . implode('', $this->wheres);
316
        }
317
318
        $this->query($sql, $this->bindings);
319
320
        return $this;
321
    }
322
323
    private function setField()
324
    {
325
        $sql = '';
326
327
        foreach ($this->data as $key => $value) {
328
            $sql .= '`' . $key . '` = ? ,';
329
        }
330
331
        $sql = rtrim($sql, ' ,');
332
333
        return $sql;
334
    }
335
336
    private function addToBindings($value)
337
    {
338
        if (is_array($value)) {
339
            $this->bindings = array_merge($this->bindings, array_values($value));
340
        } else {
341
            $this->bindings[] = $value;
342
        }
343
    }
344
345
    public function query(...$bindings)
346
    {
347
        $sql = array_shift($bindings);
348
349
        if (count($bindings) == 1 and is_array($bindings[0])) {
350
            $bindings = $bindings[0];
351
        }
352
353
        try {
354
            $query = $this->connection()->prepare($sql);
355
356
            foreach ($bindings as $key => $value) {
357
                if ($value === null) {
358
                    $query->bindValue($key + 1, $value);
359
                } else {
360
                    $query->bindValue($key + 1, _e($value));
361
                }
362
            }
363
364
            $query->execute();
365
366
            $this->reset();
367
368
            return $query;
369
        } catch (PDOException $e) {
370
            throw new Exception($e->getMessage());
371
        }
372
    }
373
374
    private function reset()
375
    {
376
        $this->table = null;
377
378
        $this->rows = 0;
379
380
        $this->data = [];
381
382
        $this->bindings = [];
383
384
        $this->selects = [];
385
386
        $this->joins = [];
387
388
        $this->wheres = [];
389
390
        $this->havings = [];
391
392
        $this->orderBy = [];
393
394
        $this->limit = null;
395
396
        $this->offset = 0;
397
398
        $this->groupBy = [];
399
    }
400
}
401