Passed
Push — master ( ef52b7...585880 )
by Mike
02:44
created

Caching::makeCacheKey()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 5
nc 1
nop 3
dl 0
loc 11
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 disableCache()
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);
1 ignored issue
show
Bug introduced by
$this of type GeneaLabs\LaravelModelCaching\Traits\Caching is incompatible with the type Illuminate\Database\Eloquent\Model expected by parameter $instance of GeneaLabs\LaravelModelCa...getModelCacheCooldown(). ( Ignorable by Annotation )

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

43
        [$cacheCooldown] = $this->getModelCacheCooldown(/** @scrutinizer ignore-type */ $this);
Loading history...
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 ?? [];
1 ignored issue
show
Bug Best Practice introduced by
The property eagerLoad does not exist on GeneaLabs\LaravelModelCaching\Traits\Caching. Did you maybe forget to declare it?
Loading history...
71
        $model = $this->model ?? $this;
1 ignored issue
show
Bug Best Practice introduced by
The property model does not exist on GeneaLabs\LaravelModelCaching\Traits\Caching. Did you maybe forget to declare it?
Loading history...
72
        $query = $this->query ?? app(Builder::class);
1 ignored issue
show
Bug Best Practice introduced by
The property query does not exist on GeneaLabs\LaravelModelCaching\Traits\Caching. Did you maybe forget to declare it?
Loading history...
73
74
        return (new CacheKey($eagerLoad, $model, $query))
1 ignored issue
show
Bug introduced by
It seems like $model can also be of type GeneaLabs\LaravelModelCaching\Traits\Caching; however, parameter $model of GeneaLabs\LaravelModelCa...CacheKey::__construct() does only seem to accept Illuminate\Database\Eloquent\Model, maybe add an additional type check? ( Ignorable by Annotation )

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

74
        return (new CacheKey($eagerLoad, /** @scrutinizer ignore-type */ $model, $query))
Loading history...
75
            ->make($columns, $idColumn, $keyDifferentiator);
76
    }
77
78
    protected function makeCacheTags() : array
79
    {
80
        $tags = (new CacheTags($this->eagerLoad ?? [], $this->model ?? $this))
3 ignored issues
show
Bug Best Practice introduced by
The property eagerLoad does not exist on GeneaLabs\LaravelModelCaching\Traits\Caching. Did you maybe forget to declare it?
Loading history...
Bug introduced by
It seems like $this->model ?? $this can also be of type GeneaLabs\LaravelModelCaching\Traits\Caching; however, parameter $model of GeneaLabs\LaravelModelCa...acheTags::__construct() does only seem to accept Illuminate\Database\Eloquent\Model, maybe add an additional type check? ( Ignorable by Annotation )

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

80
        $tags = (new CacheTags($this->eagerLoad ?? [], /** @scrutinizer ignore-type */ $this->model ?? $this))
Loading history...
Bug Best Practice introduced by
The property model does not exist on GeneaLabs\LaravelModelCaching\Traits\Caching. Did you maybe forget to declare it?
Loading history...
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