Completed
Pull Request — master (#81)
by
unknown
03:12
created

Cachable::retrieveEagerLoad()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.6666
c 0
b 0
f 0
cc 3
eloc 5
nc 3
nop 0
1
<?php namespace GeneaLabs\LaravelModelCaching\Traits;
2
3
use GeneaLabs\LaravelModelCaching\CacheKey;
4
use GeneaLabs\LaravelModelCaching\CacheTags;
5
use GeneaLabs\LaravelModelCaching\CachedModel;
6
use Illuminate\Cache\TaggableStore;
7
use Illuminate\Database\Query\Builder;
8
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
9
use GeneaLabs\LaravelModelCaching\CachedBuilder;
10
use Illuminate\Database\Eloquent\Model;
11
12
use GeneaLabs\LaravelModelCaching\CacheGlobal;
13
14
trait Cachable
15
{
16
    protected $isCachable = true;
17
18
    protected function cache(array $tags = [])
19
    {
20
        $cache = cache();
21
22
        if (config('laravel-model-caching.store')) {
23
            $cache = $cache->store(config('laravel-model-caching.store'));
24
        }
25
26
        if (is_subclass_of($cache->getStore(), TaggableStore::class)) {
27
            if (is_a($this, Model::class)) {
28
                array_push($tags, $this->makeCachePrefix(str_slug(get_called_class())));
29
            }
30
31
            $cache = $cache->tags($tags);
32
        }
33
34
        return $cache;
35
    }
36
37
    public function disableCache()
38
    {
39
40
        CacheGlobal::disableCache();
41
42
        $this->isCachable = false;
43
44
        return $this;
45
    }
46
47
    public function flushCache(array $tags = [])
48
    {
49
        if (count($tags) === 0) {
50
            $tags = $this->makeCacheTags();
51
        }
52
53
        $this->cache($tags)->flush();
54
    }
55
56
    protected function retrieveEagerLoad()
57
    {
58
        if (is_a($this, Model::class)) {
59
            return [];
60
        }
61
        if (is_a($this, EloquentBuilder::class)) {
62
            return $this->eagerLoad ?? [];
0 ignored issues
show
Bug introduced by
The property eagerLoad is declared protected in Illuminate\Database\Eloquent\Builder and cannot be accessed from this context.
Loading history...
63
        }
64
        return null;
65
    }
66
67
    protected function retrieveCacheModel()
68
    {
69
        if (is_a($this, Model::class)) {
70
            return $this;
71
        }
72
        if (is_a($this, EloquentBuilder::class)) {
73
            return $this->model;
0 ignored issues
show
Bug introduced by
The property model is declared protected in Illuminate\Database\Eloquent\Builder and cannot be accessed from this context.
Loading history...
74
        }
75
        return null;
76
    }
77
78
    protected function retrieveCacheQuery()
79
    {
80
        if (is_a($this, Model::class)) {
81
            return app(Builder::class);
82
        }
83
        if (is_a($this, EloquentBuilder::class)) {
84
            return $this->query;
0 ignored issues
show
Bug introduced by
The property query is declared protected in Illuminate\Database\Eloquent\Builder and cannot be accessed from this context.
Loading history...
85
        }
86
        return null;
87
    }
88
89
    protected function makeCachePrefix($elementMix)
90
    {
91
        $model = $this->retrieveCacheModel();
92
        if (!method_exists($model, "getCachePrefix")) {
93
            return $elementMix;
94
        }
95
96
        $result = null;
97
        $cachePrefix = $model->getCachePrefix();
98
        if ($cachePrefix == null) {
99
            return $elementMix;
100
        }
101
        if (is_array($elementMix)) {
102
            $result = [];
103
            foreach ($elementMix as $value) {
104
                array_push($result, $cachePrefix . '-' . $value);
0 ignored issues
show
Bug introduced by
Are you sure $cachePrefix of type mixed|Illuminate\Database\Eloquent\Builder can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

104
                array_push($result, /** @scrutinizer ignore-type */ $cachePrefix . '-' . $value);
Loading history...
105
            }
106
            return $result;
107
        } else {
108
            $result = $cachePrefix . '-' . $elementMix;
109
        }
110
        return $result;
111
    }
112
113
    protected function makeCacheKey(
114
        array $columns = ['*'],
115
        $idColumn = null,
116
        string $keyDifferentiator = ''
117
    ) : string {
118
        $eagerLoad = $this->retrieveEagerLoad();
119
        $model = $this->retrieveCacheModel();
120
        $query = $this->retrieveCacheQuery();
121
122
        return (new CacheKey($eagerLoad, $model, $query))
123
            ->make($columns, $idColumn, $this->makeCachePrefix($keyDifferentiator));
124
    }
125
126
    protected function makeCacheTags() : array
127
    {
128
        $eagerLoad = $this->retrieveEagerLoad();
129
        $model = $this->retrieveCacheModel();
130
131
        $tags = (new CacheTags($eagerLoad, $model))
132
            ->make();
133
134
        $tags = $this->makeCachePrefix($tags);
135
136
        return $tags;
137
    }
138
139
    public static function bootCachable()
140
    {
141
        static::saved(function ($instance) {
142
            $instance->flushCache();
143
        });
144
    }
145
146
    public static function all($columns = ['*'])
147
    {
148
        if (CacheGlobal::isDisabled()) {
149
            return parent::all($columns);
150
        }
151
152
        $class = get_called_class();
153
        $instance = new $class;
154
        $tags = $this->makeCachePrefix([str_slug(get_called_class())]);
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using $this inside a static method is generally not recommended and can lead to errors in newer PHP versions.
Loading history...
155
        $key = $instance->makeCacheKey();
156
157
        return $instance->cache($tags)
158
            ->rememberForever($key, function () use ($columns) {
159
                return parent::all($columns);
160
            });
161
    }
162
163
    public function newEloquentBuilder($query)
164
    {
165
        if (CacheGlobal::isDisabled()) {
166
            CacheGlobal::enableCache();
167
168
            return new EloquentBuilder($query);
169
        }
170
171
        return new CachedBuilder($query);
172
    }
173
}
174