Completed
Pull Request — master (#22)
by Sergey
19:00 queued 03:57
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\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
    }
46
47
    public function getPrimaryKey(): string
48
    {
49
        if ($this->primaryKey == null) {
50
            $this->setPrimaryKey($this->{static::PRIMARY_KEY});
51
        }
52
        return $this->primaryKey;
53
    }
54
55
    final public static function getCollection(): string
56
    {
57
        if (static::COLLECTION == null) {
58
            throw new IllegalCollectionException();
59
        }
60
        return static::COLLECTION;
61
    }
62
63
    public function exists(bool $value = null): bool
64
    {
65
        if ($value != null) {
66
            $this->exists = $value;
67
        }
68
        return $this->exists;
69
    }
70
71
    public static function all(IQueryBuilder $query, callable $callback = null): ICollection
72
    {
73
        $collection = static::di()->getRepository()->all(
74
            $query,
75
            static::class,
76
            function (IEloquent $model) use ($callback) {
77
                $model->exists(true);
78
                if ($callback != null) {
79
                    $callback($model);
80
                }
81
            });
82
        return $collection;
83
    }
84
85
    public static function find($id, array $columns = []): IEloquent
86
    {
87
        $model = static::di()->getRepository()->find($id, static::class, $columns);
88
        if ($model != null) {
89
            $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...
90
        }
91
        return $model;
92
    }
93
94
    public static function findOrFail($id, array $columns = []): IEloquent
95
    {
96
        $model = static::find($id, $columns);
97
        if ($model == null) {
98
            throw new ModelNotFoundException(get_called_class(), $id);
99
        }
100
        return $model;
101
    }
102
103
    public static function create(array $attributes): IEloquent
104
    {
105
        $model = new static($attributes);
106
        $model->save();
107
        return $model;
108
    }
109
110
    public static function destroy($id)
111
    {
112
        static::findOrFail($id)->delete();
113
    }
114
115
    public function save(array $columns = [])
116
    {
117
        if ($this->saving() === false) {
118
            return;
119
        }
120
        $repository = $this->di()->getRepository();
121
        if ($this->timestamps) {
122
            $this->updateTimestamps();
123
        }
124
        if (!$this->exists) {
125
            $repository->insert($this);
126
        } else {
127
            $repository->update($this);
128
        }
129
        $this->exists = true;
130
        if ($this->saved() === false) {
131
            return;
132
        }
133
    }
134
135
    public function delete()
136
    {
137
        if ($this->deleting() === false) {
138
            return;
139
        }
140
        $this->di()->getRepository()->delete($this);
141
        $this->exists = false;
142
        if ($this->deleted() === false) {
143
            return;
144
        }
145
    }
146
}