Completed
Pull Request — master (#22)
by Sergey
15:55
created

Eloquent::save()   B

Complexity

Conditions 5
Paths 9

Size

Total Lines 19
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 19
rs 8.8571
c 0
b 0
f 0
nc 9
cc 5
eloc 13
nop 1
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\IllegalModelHashException;
9
use Isswp101\Persimmon\Exceptions\ModelNotFoundException;
10
use Isswp101\Persimmon\Helpers\EloquentHash;
11
use Isswp101\Persimmon\QueryBuilder\IQueryBuilder;
12
use Isswp101\Persimmon\Traits\Containerable;
13
use Isswp101\Persimmon\Traits\Eventable;
14
use Isswp101\Persimmon\Traits\Timestampable;
15
16
/**
17
 * @TODO
18
 * 1. Cache
19
 * 2. Consider columns when searching
20
 * 3. Check __clone()
21
 */
22
abstract class Eloquent implements IEloquent
23
{
24
    use Containerable, Timestampable, Eventable;
25
26
    protected $primaryKey;
27
    protected $exists = false;
28
    protected $timestamps = false;
29
    protected $cache = false;
30
31
    /** @MustBeOverridden */
32
    const COLLECTION = null;
33
34
    const PRIMARY_KEY = 'id';
35
    const CREATED_AT = 'created_at';
36
    const UPDATED_AT = 'updated_at';
37
38
    abstract protected static function di(): Container;
39
40
    public function __construct(array $attributes = [])
41
    {
42
        $this->fill($attributes);
43
    }
44
45
    public function setPrimaryKey(string $key)
46
    {
47
        $this->primaryKey = $key;
48
    }
49
50
    public function getPrimaryKey(): string
51
    {
52
        if ($this->primaryKey == null) {
53
            $this->setPrimaryKey($this->{static::PRIMARY_KEY});
54
        }
55
        return $this->primaryKey;
56
    }
57
58
    final public static function getCollection(): string
59
    {
60
        if (static::COLLECTION == null) {
61
            throw new IllegalCollectionException();
62
        }
63
        return static::COLLECTION;
64
    }
65
66
    public function exists(bool $value = null): bool
67
    {
68
        if ($value != null) {
69
            $this->exists = $value;
70
        }
71
        return $this->exists;
72
    }
73
74
    public static function all(IQueryBuilder $query, callable $callback = null): ICollection
75
    {
76
        $collection = static::di()->getRepository()->all($query, static::class,
77
            function (IEloquent $model) use ($callback) {
78
                $model->exists(true);
79
                if ($callback != null) {
80
                    $callback($model);
81
                }
82
            });
83
        return $collection;
84
    }
85
86
    public static function find($id, array $columns = []): IEloquent
87
    {
88
        $di = static::di();
89
        $cache = $di->getCache()->get(EloquentHash::make(static::class, $id));
90
        $cache->getCachedAttributes();
91
92
        $model = static::di()->getRepository()->find($id, static::class, $columns);
93
        if ($model != null) {
94
            $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...
95
        }
96
        return $model;
97
    }
98
99
    public static function findOrFail($id, array $columns = []): IEloquent
100
    {
101
        $model = static::find($id, $columns);
102
        if ($model == null) {
103
            throw new ModelNotFoundException(get_called_class(), $id);
104
        }
105
        return $model;
106
    }
107
108
    public static function create(array $attributes): IEloquent
109
    {
110
        $model = new static($attributes);
111
        $model->save();
112
        return $model;
113
    }
114
115
    public static function destroy($id)
116
    {
117
        static::findOrFail($id)->delete();
118
    }
119
120
    public function save(array $columns = [])
121
    {
122
        if ($this->saving() === false) {
123
            return;
124
        }
125
        $repository = $this->di()->getRepository();
126
        if ($this->timestamps) {
127
            $this->updateTimestamps();
128
        }
129
        if (!$this->exists) {
130
            $repository->insert($this);
131
        } else {
132
            $repository->update($this);
133
        }
134
        $this->exists = true;
135
        if ($this->saved() === false) {
136
            return;
137
        }
138
    }
139
140
    public function delete()
141
    {
142
        if ($this->deleting() === false) {
143
            return;
144
        }
145
        $this->di()->getRepository()->delete($this);
146
        $this->exists = false;
147
        if ($this->deleted() === false) {
148
            return;
149
        }
150
    }
151
152
    public function getHash(): string
153
    {
154
        if ($this->getPrimaryKey() == null) {
155
            throw new IllegalModelHashException($this);
156
        }
157
        return EloquentHash::make(get_class($this), $this->getPrimaryKey());
158
    }
159
}