Completed
Pull Request — master (#22)
by Sergey
14:20
created

Eloquent::getPrimaryKey()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

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