Passed
Push — master ( fe19bd...35c88b )
by Mike
02:28
created

Caching::disableModelCaching()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
1
<?php namespace GeneaLabs\LaravelModelCaching\Traits;
2
3
use GeneaLabs\LaravelModelCaching\CacheKey;
4
use GeneaLabs\LaravelModelCaching\CacheTags;
5
use Illuminate\Cache\TaggableStore;
6
use Illuminate\Database\Eloquent\Model;
7
use Illuminate\Database\Query\Builder;
8
9
trait Caching
10
{
11
    protected $isCachable = true;
12
13
    public function cache(array $tags = [])
14
    {
15
        $cache = cache();
16
17
        if (config('laravel-model-caching.store')) {
18
            $cache = $cache->store(config('laravel-model-caching.store'));
19
        }
20
21
        if (is_subclass_of($cache->getStore(), TaggableStore::class)) {
22
            $cache = $cache->tags($tags);
23
        }
24
25
        return $cache;
26
    }
27
28
    public function disableModelCaching()
29
    {
30
        $this->isCachable = false;
31
32
        return $this;
33
    }
34
35
    public function flushCache(array $tags = [])
36
    {
37
        if (count($tags) === 0) {
38
            $tags = $this->makeCacheTags();
39
        }
40
41
        $this->cache($tags)->flush();
42
43
        [$cacheCooldown] = $this->getModelCacheCooldown($this);
44
45
        if ($cacheCooldown) {
46
            $cachePrefix = $this->getCachePrefix();
47
            $modelClassName = get_class($this);
48
            $cacheKey = "{$cachePrefix}:{$modelClassName}-cooldown:saved-at";
49
50
            $this->cache()
51
                ->rememberForever($cacheKey, function () {
52
                    return now();
53
                });
54
        }
55
    }
56
57
    protected function getCachePrefix() : string
58
    {
59
        return "genealabs:laravel-model-caching:"
60
            . (config('laravel-model-caching.cache-prefix')
61
                ? config('laravel-model-caching.cache-prefix', '') . ":"
62
                : "");
63
    }
64
65
    protected function makeCacheKey(
66
        array $columns = ['*'],
67
        $idColumn = null,
68
        string $keyDifferentiator = ''
69
    ) : string {
70
        $eagerLoad = $this->eagerLoad ?? [];
71
        $model = $this->model ?? $this;
72
        $query = $this->query ?? app(Builder::class);
73
74
        return (new CacheKey($eagerLoad, $model, $query))
75
            ->make($columns, $idColumn, $keyDifferentiator);
76
    }
77
78
    protected function makeCacheTags() : array
79
    {
80
        $tags = (new CacheTags($this->eagerLoad ?? [], $this->model ?? $this))
81
            ->make();
82
83
        return $tags;
84
    }
85
86
    public function getModelCacheCooldown(Model $instance)
87
    {
88
        $cachePrefix = $this->getCachePrefix();
89
        $modelClassName = get_class($instance);
90
        [$cacheCooldown, $invalidatedAt, $savedAt] = $this
91
            ->getCacheCooldownDetails($instance, $cachePrefix, $modelClassName);
92
93
        if (! $cacheCooldown || $cacheCooldown === 0) {
94
            return [null, null, null];
95
        }
96
97
        return [
98
            $cacheCooldown,
99
            $invalidatedAt,
100
            $savedAt,
101
        ];
102
    }
103
104
    protected function getCacheCooldownDetails(
105
        Model $instance,
106
        string $cachePrefix,
107
        string $modelClassName
108
    ) : array {
109
        return [
110
            $instance
111
                ->cache()
112
                ->get("{$cachePrefix}:{$modelClassName}-cooldown:seconds"),
113
            $instance
114
                ->cache()
115
                ->get("{$cachePrefix}:{$modelClassName}-cooldown:invalidated-at"),
116
            $instance
117
                ->cache()
118
                ->get("{$cachePrefix}:{$modelClassName}-cooldown:saved-at"),
119
        ];
120
    }
121
122
    protected function checkCooldownAndRemoveIfExpired(Model $instance)
123
    {
124
        [$cacheCooldown, $invalidatedAt] = $this->getModelCacheCooldown($instance);
125
126
        if (! $cacheCooldown
127
            || now()->diffInSeconds($invalidatedAt) < $cacheCooldown
128
        ) {
129
            return;
130
        }
131
132
        $cachePrefix = $this->getCachePrefix();
133
        $modelClassName = get_class($instance);
134
135
        $instance
136
            ->cache()
137
            ->forget("{$cachePrefix}:{$modelClassName}-cooldown:invalidated-at");
138
        $instance
139
            ->cache()
140
            ->forget("{$cachePrefix}:{$modelClassName}-cooldown:invalidated-at");
141
        $instance
142
            ->cache()
143
            ->forget("{$cachePrefix}:{$modelClassName}-cooldown:saved-at");
144
        $instance->flushCache();
145
    }
146
147
    protected function checkCooldownAndFlushAfterPersiting(Model $instance)
148
    {
149
        [$cacheCooldown, $invalidatedAt] = $instance->getModelCacheCooldown($instance);
150
151
        if (! $cacheCooldown) {
152
            $instance->flushCache();
153
154
            return;
155
        }
156
157
        $this->setCacheCooldownSavedAtTimestamp($instance);
158
159
        if (now()->diffInSeconds($invalidatedAt) >= $cacheCooldown) {
160
            $instance->flushCache();
161
        }
162
    }
163
164
    public function isCachable() : bool
165
    {
166
        return $this->isCachable
167
            && ! config('laravel-model-caching.disabled');
168
    }
169
170
    protected function setCacheCooldownSavedAtTimestamp(Model $instance)
171
    {
172
        $cachePrefix = $this->getCachePrefix();
173
        $modelClassName = get_class($instance);
174
        $cacheKey = "{$cachePrefix}:{$modelClassName}-cooldown:saved-at";
175
176
        $instance->cache()
177
            ->rememberForever($cacheKey, function () {
178
                return now();
179
            });
180
    }
181
}
182