Completed
Pull Request — master (#22)
by Sergey
17:35 queued 02:34
created

Eloquent   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 126
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 8

Importance

Changes 0
Metric Value
wmc 23
lcom 1
cbo 8
dl 0
loc 126
rs 10
c 0
b 0
f 0

13 Methods

Rating   Name   Duplication   Size   Complexity  
di() 0 1 ?
A __construct() 0 4 1
A setPrimaryKey() 0 5 1
A getPrimaryKey() 0 5 1
A getCollection() 0 7 2
A exists() 0 7 2
A all() 0 13 2
A find() 0 8 2
A findOrFail() 0 8 2
A create() 0 6 1
A destroy() 0 4 1
B save() 0 19 5
A delete() 0 11 3
1
<?php
2
3
namespace Isswp101\Persimmon\Model;
4
5
use Isswp101\Persimmon\Collection\ICollection;
6
use Isswp101\Persimmon\DI\Container;
7
use Isswp101\Persimmon\Exceptions\IllegalCollectionException;
8
use Isswp101\Persimmon\Exceptions\ModelNotFoundException;
9
use Isswp101\Persimmon\QueryBuilder\IQueryBuilder;
10
use Isswp101\Persimmon\Traits\Containerable;
11
use Isswp101\Persimmon\Traits\Eventable;
12
use Isswp101\Persimmon\Traits\Timestampable;
13
14
/**
15
 * @TODO
16
 * 1. Cache
17
 * 2. Consider columns when searching
18
 * 3. Check __clone()
19
 */
20
abstract class Eloquent implements IEloquent
21
{
22
    use Containerable, Timestampable, Eventable;
23
24
    protected $primaryKey;
25
    protected $exists = false;
26
    protected $timestamps = false;
27
28
    /** @MustBeOverridden */
29
    const COLLECTION = null;
30
31
    const PRIMARY_KEY = 'id';
32
    const CREATED_AT = 'created_at';
33
    const UPDATED_AT = 'updated_at';
34
35
    abstract protected static function di(): Container;
36
37
    public function __construct(array $attributes = [])
38
    {
39
        $this->fill($attributes);
40
    }
41
42
    public function setPrimaryKey(string $key)
43
    {
44
        $this->primaryKey = $key;
45
        // $this->{static::PRIMARY_KEY} = $key;
0 ignored issues
show
Unused Code Comprehensibility introduced by
62% 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...
46
    }
47
48
    public function getPrimaryKey(): string
49
    {
50
        return $this->primaryKey;
51
        // return $this->{static::PRIMARY_KEY};
0 ignored issues
show
Unused Code Comprehensibility introduced by
73% 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...
52
    }
53
54
    final public static function getCollection(): string
55
    {
56
        if (static::COLLECTION == null) {
57
            throw new IllegalCollectionException();
58
        }
59
        return static::COLLECTION;
60
    }
61
62
    public function exists(bool $value = null): bool
63
    {
64
        if ($value != null) {
65
            $this->exists = $value;
66
        }
67
        return $this->exists;
68
    }
69
70
    public static function all(IQueryBuilder $query, callable $callback = null): ICollection
71
    {
72
        $collection = static::di()->getRepository()->all(
73
            $query,
74
            static::class,
75
            function (IEloquent $model) use ($callback) {
76
                $model->exists(true);
77
                if ($callback != null) {
78
                    $callback($model);
79
                }
80
            });
81
        return $collection;
82
    }
83
84
    public static function find($id, array $columns = []): IEloquent
85
    {
86
        $model = static::di()->getRepository()->find($id, static::class, $columns);
87
        if ($model != null) {
88
            $model->exists = true;
0 ignored issues
show
Bug introduced by
Accessing exists on the interface Isswp101\Persimmon\Contracts\Storable suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
89
        }
90
        return $model;
91
    }
92
93
    public static function findOrFail($id, array $columns = []): IEloquent
94
    {
95
        $model = static::find($id, $columns);
96
        if ($model == null) {
97
            throw new ModelNotFoundException(get_called_class(), $id);
98
        }
99
        return $model;
100
    }
101
102
    public static function create(array $attributes): IEloquent
103
    {
104
        $model = new static($attributes);
105
        $model->save();
106
        return $model;
107
    }
108
109
    public static function destroy($id)
110
    {
111
        static::findOrFail($id)->delete();
112
    }
113
114
    public function save(array $columns = [])
115
    {
116
        if ($this->saving() === false) {
117
            return;
118
        }
119
        $repository = $this->di()->getRepository();
120
        if ($this->timestamps) {
121
            $this->updateTimestamps();
122
        }
123
        if (!$this->exists) {
124
            $repository->insert($this);
125
        } else {
126
            $repository->update($this);
127
        }
128
        $this->exists = true;
129
        if ($this->saved() === false) {
130
            return;
131
        }
132
    }
133
134
    public function delete()
135
    {
136
        if ($this->deleting() === false) {
137
            return;
138
        }
139
        $this->di()->getRepository()->delete($this);
140
        $this->exists = false;
141
        if ($this->deleted() === false) {
142
            return;
143
        }
144
    }
145
}