Passed
Branch master (c15be5)
by Henri
01:39 queued 22s
created

Datamanager::check_primaryAuto()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 0

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 0
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 2
rs 10
1
<?php
2
3
namespace HnrAzevedo\Datamanager;
4
5
use Exception;
6
7
abstract class Datamanager
8
{
9
    use CrudTrait;
10
11
    private ?string $table = null;
12
    private ?string $primary = null;
13
    private array $result = [];
14
    protected array $data = [];
15
    
16
    private bool $full = false;
17
    private ?string $clause = null;
18
19
20
    private array $where = [''=> ["1",'=',"1"] ];
21
    private ?string $order = null;
22
    private ?string $limit = null;
23
    private ?int $offset = null;
24
    private array $excepts = [];
25
    private int $count = 0;
26
    private array $select = [];
27
    private ?string $query = null;
28
29
30
    protected function create(string $table, string $primary): Datamanager
31
    {
32
        $this->table = $table;
33
        $this->primary = $primary;
34
        $describe = $this->describe();
35
        
36
        $this->check_fail();
37
38
        $this->mountData($describe);
39
        $this->full = true;
40
        return $this;
41
    }
42
43
    private function mountData(array $table): Datamanager
44
    {
45
        foreach ($table as $column) {
46
            $field = null;
47
            foreach ($column as $propriety => $value) {
48
                switch ($propriety) {
49
                    case 'Field':
50
                        $field = $value;
51
                        $this->$field = null;
52
                        break;
53
                    case 'Type':
54
                        $type = $value;
55
56
                        if(strpos($value,'(')){
57
                            switch (substr($value,0,strpos($value,'('))) {
58
                                case 'varchar':
59
                                case 'char':
60
                                case 'text': $type = 'string'; break;
61
                                case 'tinyint':
62
                                case 'mediumint':
63
                                case 'smallint':
64
                                case 'bigint':
65
                                case 'int': $type = 'int'; break;
66
                                case 'decimal':
67
                                case 'float':
68
                                case 'double':
69
                                case 'real': $type = 'float'; break;
70
                                default: $type = $value; break;
71
                            }
72
                        }
73
74
                        switch ($type) {
75
                            case 'string':
76
                            case 'float':
77
                            case 'int':
78
                                $this->$field = ['maxlength' => substr($value,(strpos($value,'(')+1),-1) ]; 
79
                                break;
80
                            case 'date':
81
                                $this->$field = ['maxlength' => 10];
82
                                break;
83
                            case 'datetime':
84
                                $this->$field = ['maxlength' => 19];
85
                                break;
86
                            case 'boolean':
87
                                $this->$field = ['maxlength' => 1];
88
                                break;
89
                            default:
90
                                $this->$field = ['maxlength' => null];
91
                                break;
92
                        }
93
94
                        $this->$field = ['type' => $type];
95
                        break;
96
                    case 'Null':
97
                        $this->$field = ['null' => ($value === 'YES') ? 1 : 0];
98
                        break;
99
                    case 'Key':
100
                        $this->$field = ['key' => $value];
101
                        $this->$field = ['upgradeable' => ($value == 'PRI') ? 0 : 1];
102
                        break;
103
                    case 'Extra':
104
                        $this->$field = ['extra' => $value];
105
                        break;
106
                    case 'Default':
107
                        $this->$field = ['default' => $value];
108
                        $this->$field = ['value' => null];
109
                        $this->$field = ['changed' => false];
110
                        $this->select[$field] = true;
111
                        break;
112
                }
113
            }
114
        }
115
        return $this;
116
    }
117
118
    public function __set(string $prop,$value): Datamanager
119
    {
120
121
        if(is_array($value)){
122
            $attr = array_keys($value)[0];
123
            $this->data[$prop][$attr] = $value[$attr];
124
            return $this;
125
        }
126
127
        if($this->full && !array_key_exists($prop,$this->data)){
128
            throw new Exception("{$prop} field does not exist in the table {$this->table}.");
129
        }
130
131
        $this->data[$prop]['changed'] = true;
132
        $this->data[$prop]['value'] = $value;
133
        
134
        return $this;
135
    }
136
137
    public function getData(): ?array
138
    {
139
        return $this->data;
140
    }
141
142
    public function __get(string $field)
143
    {
144
        if($this->full && !array_key_exists($field,$this->data)){
145
            throw new Exception("{$field} field does not exist in the table {$this->table}.");
146
        }
147
148
        return $this->data[$field]['value'];
149
    }
150
151
    public function getCount(): int
152
    {
153
        return $this->count;
154
    }
155
156
    public function except($deniable): Datamanager
157
    {
158
        $deniable = (is_array($deniable)) ? $deniable : [$deniable];
159
160
        foreach ($deniable as $field) {
161
            if(!array_key_exists($field,$this->data)){
162
                throw new Exception("{$field} field does not exist in the table {$this->table}.");
163
            }
164
165
            $this->excepts[$field] = true;
166
        }
167
168
        return $this;
169
    }
170
171
    public function deny(): Datamanager
172
    {
173
        foreach ($this->excepts as $field => $value) {
174
            unset($this->select[$field]);
175
        }
176
        return $this;
177
    }
178
179
    public function orderBy(string $field, string $ord = 'ASC'): Datamanager
180
    {
181
        if(!array_key_exists(str_replace(['asc','ASC','desc','DESC',' '],'',$field),$this->data) && $this->full){
182
            throw new Exception("{$field} field does not exist in the table {$this->table}.");
183
        }
184
185
        if(strpos(strtolower($field),'asc') || strpos(strtolower($field),'desc')){
186
            $ord = '';
187
        }
188
189
        $this->order = " ORDER BY {$field} {$ord} ";
190
        return $this;
191
    }
192
193
    public function only($params): Datamanager
194
    {
195
        $params = (is_array($params)) ? $params : [$params];
196
        $this->select = [];
197
198
        foreach ($params as $field) {
199
200
            if(!array_key_exists($field,$this->data) && $this->full){
201
                throw new Exception("{$field} field does not exist in the table {$this->table}.");
202
            }
203
204
            $this->select[$field] = true;
205
        }
206
        $this->select[$this->primary] = true;
207
208
        return $this;
209
    }
210
211
    public function where(array $where): Datamanager
212
    {
213
        $this->where['AND'] = (array_key_exists('AND',$this->where)) ?? '';
214
        $w = [];
215
        foreach ($where as $condition => $values) {
216
217
            if(!is_array($values)){
218
                $w['AND'][] = $values;
219
                continue;
220
            }
221
222
            $this->check_where_array($values);
223
224
            $w[(is_int($condition) ? 'AND' : $condition)][] = $values;
225
                       
226
        }
227
228
        $this->where = array_merge($this->where,$w);
229
230
        return $this;
231
    }
232
233
    public function check_where_array(array $where)
234
    {
235
        if(count($where) != 3){
236
            throw new Exception("Condition where set incorrectly: ".implode(' ',$where));
237
        }
238
239
        if(!array_key_exists($where[0],$this->data) && $this->full){
240
            throw new Exception("{$where[0]} field does not exist in the table {$this->table}.");
241
        }
242
    }
243
244
    public function limit(string $limit): Datamanager
245
    {
246
        $this->limit = $limit;
247
        return $this;
248
    }
249
250
    public function offset(int $offset): Datamanager
251
    {
252
        if(is_null($this->limit)){
253
            throw new Exception("The limit must be set before the offset.");
254
        }
255
256
        $this->offset = $offset;
257
        return $this;
258
    }
259
260
    public function result(): array
261
    {
262
        return $this->result;
263
    }
264
265
    public function first(): Datamanager
266
    {
267
        return  (count($this->result) > 0) ? $this->setByDatabase($this->result[0]) : $this;
268
    }
269
270
    public function setByDatabase(array $arrayValues): Datamanager
271
    {
272
        $clone = clone $this;
273
        
274
        $clone->result = [
275
            0 => $this->result[0]
276
        ];
277
278
        $clone->count = 1;
279
280
        foreach ($arrayValues as $key => $value) {
281
282
            if(!array_key_exists($key,$this->data)){
283
                throw new Exception("{$key} field does not exist in the table {$this->table}.");
284
            }
285
286
            $clone->data[$key]['value'] = $value;
287
        }
288
        return $clone;
289
    }
290
291
    public function toJson(): string
292
    {
293
        $string = '';
294
        foreach ($this->data as $key => $value) {
295
296
            if(gettype($value)==='object'){
297
                $value = $value->getData()[$this->primary]['value'];
298
            }
299
300
            $string .= '"'.$key.'"'.':"'.$value.'",';
301
        }
302
        return str_replace(',}', '}', '{'.$string.'}');
303
    }
304
305
    public function remove(?bool $exec = false): Datamanager
306
    {
307
        if($exec){
308
            $this->clause = null;
309
310
            if(count($this->where) == 1){
311
                $this->removeById();
312
                return $this;
313
            }
314
315
            $where = '';
316
            $data = '';
317
            foreach($this->where as $clause => $condition){
318
                if(strlen($clause) === 0){
319
                    $where .= " {$clause} ";
320
                    $where .= " {$condition[0]} {$condition[1]} :q_{$condition[0]} ";
321
                    $data .= "q_{$condition[0]}={$condition[2]}&";
322
                    continue;
323
                }
324
                
325
                foreach($condition as $column => $value){
326
                    $where .= " {$clause} ";
327
                    $where .= " {$value[0]} {$value[1]} :q_{$value[0]} ";
328
                    $data .= "q_{$value[0]}={$value[2]}&";
329
                }
330
            }
331
332
            $this->delete($where, substr($data,0,-1) );
333
334
            $this->check_fail();
335
            
336
            return $this;
337
        }
338
339
        $this->clause = 'remove';
340
        
341
        return $this;
342
    }
343
344
    private function removeById(): bool
345
    {
346
        $delete = $this->delete("{$this->primary}=:{$this->primary}","{$this->primary}={$this->getData()[$this->primary]['value']}");
347
348
        $this->check_fail();
349
350
        return $delete;
351
    }
352
353
    public function check_primaryAuto()
354
    {
355
356
    }
357
358
    public function save(): Datamanager
359
    {
360
        $data = [];
361
        foreach ($this->data as $key => $value) {
362
            if(strstr($this->data[$key]['extra'],'auto_increment') && $key != $this->primary){
363
                continue;
364
            }
365
366
            if($this->data[$key]['changed'] && $this->data[$key]['upgradeable'] || $this->primary == $key){
0 ignored issues
show
introduced by
Consider adding parentheses for clarity. Current Interpretation: ($this->data[$key]['chan... $this->primary == $key, Probably Intended Meaning: $this->data[$key]['chang...$this->primary == $key)
Loading history...
367
                $data[$key] = $this->data[$key]['value'];
368
            }
369
        }
370
371
        $terms = "{$this->primary}=:{$this->primary}";
372
        $params = $this->primary.'='.$this->getData()[$this->primary]['value'];
373
374
        $this->transaction('begin');
375
        try{
376
            $this->update($data, $terms, $params);
377
378
            $this->check_fail();
379
380
            $this->transaction('commit');
381
        }catch(Exception $er){
382
            $this->transaction('rollback');
383
            throw $er;
384
        }
385
386
        return $this;
387
    }
388
389
    public function persist(): Datamanager
390
    {
391
        $columns = '';
392
        $values = '';
393
        $data = [];
394
395
        foreach ($this->data as $key => $value) {
396
            if(strstr($this->data[$key]['extra'],'auto_increment')){
397
                continue;
398
            }
399
400
            if(strlen($value['value']) > $value['maxlength']){
401
                throw new Exception("The information provided for column {$key} of table {$this->table} exceeded that allowed.");
402
            }
403
404
            $columns .= $key.',';
405
            $values .= ':'.$key.',';
406
            $data[$key] = $value['value'];
407
        }
408
409
        $this->transaction('begin');
410
        try{
411
           
412
            $id = $this->insert($data);
413
414
            $this->check_fail();
415
416
            $this->getData()[$this->primary]['value'] = $id;
417
            
418
            $this->transaction('commit');
419
420
        }catch(Exception $er){
421
            $this->transaction('rollback');
422
            throw $er;
423
        }
424
425
        return $this;
426
    }
427
428
    public function toEntity()
429
    {
430
        if($this->getCount() === 0){
431
            return null;
432
        }
433
434
        $entity = $this->setByDatabase($this->result[0]);
435
436
        if(count($this->result) > 1){
437
            $entity = [];
438
            foreach ($this->result as $key => $value) {
439
                $entity[] = $this->setByDatabase($value);
440
            }
441
        }
442
443
        return $entity;
444
    }
445
446
    public function findById($id): Datamanager
447
    {
448
        $this->where([$this->primary,'=',$id]);
449
        return $this;
450
    }
451
452
    public function execute(): Datamanager
453
    {
454
        if(!is_null($this->clause)){
455
            if($this->clause == 'remove'){
456
                return $this->remove(true);
457
            }
458
        }
459
460
        $this->deny();
461
        $select = '';
462
463
        foreach ($this->select as $key => $value) {
464
            $select .= "{$key},";
465
        }
466
        
467
        $select = substr($select,0,-1);
468
        $this->query = str_replace("*",$select,$this->query);
469
470
        $where = '';
471
        $whereData = [];
472
        foreach ($this->where as $key => $value) {
473
            $key = (!$key) ? '' : " {$key} ";
474
475
            
476
            if(is_array($value[0])){
477
                foreach ($value as $k => $v) {
478
                    $where .= " {$key} {$v[0]} {$v[1]} :q_{$v[0]} ";
479
                    $whereData["q_{$v[0]}"] = $v[2];
480
                }
481
            }else{
482
                $where .= " {$key} {$value[0]} {$value[1]} :q_{$value[0]} ";
483
                $whereData["q_{$value[0]}"] = $value[2];
484
            }
485
486
        }
487
        $where = substr($where,0,-1);
488
        $this->query .= " WHERE {$where} ";
489
490
        $this->query .= $this->order;
491
492
        if(!is_null($this->limit)){
493
            $this->query .= " LIMIT {$this->limit}";
494
        }
495
496
        if(!is_null($this->offset)){
497
            $this->query .= " OFFSET {$this->offset}";
498
        }
499
500
        $this->result = $this->select($this->query,$whereData);
501
502
        $this->check_fail();
503
504
        $this->count = count($this->result);
505
        $this->query = null;
506
507
        return $this;
508
    }
509
510
    public function find(?int $key = null): Datamanager
511
    {
512
        $this->query = " SELECT * FROM {$this->table} ";
513
514
        if(is_int($key)){
515
            return $this->findById($key);
516
        }
517
518
        return $this;
519
    }
520
521
}
522