|
1 | 1 | <?php namespace GeneaLabs\LaravelModelCaching\Traits; |
2 | 2 |
|
3 | | -use GeneaLabs\LaravelModelCaching\CachedBuilder; |
4 | | -use GeneaLabs\LaravelModelCaching\CachedModel; |
5 | | -use GeneaLabs\LaravelModelCaching\CacheKey; |
6 | | -use GeneaLabs\LaravelModelCaching\CacheTags; |
7 | | -use Illuminate\Cache\TaggableStore; |
8 | | -use Illuminate\Database\Eloquent\Model; |
9 | | -use Illuminate\Database\Eloquent\Builder as EloquentBuilder; |
10 | | -use Illuminate\Database\Query\Builder; |
| 3 | +use Fico7489\Laravel\Pivot\Traits\PivotEventTrait; |
11 | 4 |
|
12 | 5 | trait Cachable |
13 | 6 | { |
14 | | - protected $isCachable = true; |
15 | | - |
16 | | - public function cache(array $tags = []) |
17 | | - { |
18 | | - $cache = cache(); |
19 | | - |
20 | | - if (config('laravel-model-caching.store')) { |
21 | | - $cache = $cache->store(config('laravel-model-caching.store')); |
22 | | - } |
23 | | - |
24 | | - if (is_subclass_of($cache->getStore(), TaggableStore::class)) { |
25 | | - $cache = $cache->tags($tags); |
26 | | - } |
27 | | - |
28 | | - return $cache; |
29 | | - } |
30 | | - |
31 | | - public function disableCache() |
32 | | - { |
33 | | - $this->isCachable = false; |
34 | | - |
35 | | - return $this; |
36 | | - } |
37 | | - |
38 | | - public function flushCache(array $tags = []) |
39 | | - { |
40 | | - if (count($tags) === 0) { |
41 | | - $tags = $this->makeCacheTags(); |
42 | | - } |
43 | | - |
44 | | - $this->cache($tags)->flush(); |
45 | | - |
46 | | - [$cacheCooldown] = $this->getModelCacheCooldown($this); |
47 | | - |
48 | | - if ($cacheCooldown) { |
49 | | - $cachePrefix = $this->getCachePrefix(); |
50 | | - $modelClassName = get_class($this); |
51 | | - $cacheKey = "{$cachePrefix}:{$modelClassName}-cooldown:saved-at"; |
52 | | - |
53 | | - $this->cache() |
54 | | - ->rememberForever($cacheKey, function () { |
55 | | - return now(); |
56 | | - }); |
57 | | - } |
58 | | - } |
59 | | - |
60 | | - protected function getCachePrefix() : string |
61 | | - { |
62 | | - return "genealabs:laravel-model-caching:" |
63 | | - . (config('laravel-model-caching.cache-prefix') |
64 | | - ? config('laravel-model-caching.cache-prefix', '') . ":" |
65 | | - : ""); |
66 | | - } |
67 | | - |
68 | | - protected function makeCacheKey( |
69 | | - array $columns = ['*'], |
70 | | - $idColumn = null, |
71 | | - string $keyDifferentiator = '' |
72 | | - ) : string { |
73 | | - $eagerLoad = $this->eagerLoad ?? []; |
74 | | - $model = $this->model ?? $this; |
75 | | - $query = $this->query ?? app(Builder::class); |
76 | | - |
77 | | - return (new CacheKey($eagerLoad, $model, $query)) |
78 | | - ->make($columns, $idColumn, $keyDifferentiator); |
79 | | - } |
80 | | - |
81 | | - protected function makeCacheTags() : array |
82 | | - { |
83 | | - $tags = (new CacheTags($this->eagerLoad ?? [], $this->model ?? $this)) |
84 | | - ->make(); |
85 | | - |
86 | | - return $tags; |
87 | | - } |
88 | | - |
89 | | - public function getModelCacheCooldown(Model $instance) |
90 | | - { |
91 | | - $cachePrefix = $this->getCachePrefix(); |
92 | | - $modelClassName = get_class($instance); |
93 | | - [$cacheCooldown, $invalidatedAt, $savedAt] = $this |
94 | | - ->getCacheCooldownDetails($instance, $cachePrefix, $modelClassName); |
95 | | - |
96 | | - if (! $cacheCooldown || $cacheCooldown === 0) { |
97 | | - return [null, null, null]; |
98 | | - } |
99 | | - |
100 | | - return [ |
101 | | - $cacheCooldown, |
102 | | - $invalidatedAt, |
103 | | - $savedAt, |
104 | | - ]; |
105 | | - } |
106 | | - |
107 | | - protected function getCacheCooldownDetails( |
108 | | - Model $instance, |
109 | | - string $cachePrefix, |
110 | | - string $modelClassName |
111 | | - ) : array { |
112 | | - return [ |
113 | | - $instance |
114 | | - ->cache() |
115 | | - ->get("{$cachePrefix}:{$modelClassName}-cooldown:seconds"), |
116 | | - $instance |
117 | | - ->cache() |
118 | | - ->get("{$cachePrefix}:{$modelClassName}-cooldown:invalidated-at"), |
119 | | - $instance |
120 | | - ->cache() |
121 | | - ->get("{$cachePrefix}:{$modelClassName}-cooldown:saved-at"), |
122 | | - ]; |
123 | | - } |
124 | | - |
125 | | - protected function checkCooldownAndRemoveIfExpired(Model $instance) |
126 | | - { |
127 | | - [$cacheCooldown, $invalidatedAt] = $this->getModelCacheCooldown($instance); |
128 | | - |
129 | | - if (! $cacheCooldown |
130 | | - || now()->diffInSeconds($invalidatedAt) < $cacheCooldown |
131 | | - ) { |
132 | | - return; |
133 | | - } |
134 | | - |
135 | | - $cachePrefix = $this->getCachePrefix(); |
136 | | - $modelClassName = get_class($instance); |
137 | | - |
138 | | - $instance |
139 | | - ->cache() |
140 | | - ->forget("{$cachePrefix}:{$modelClassName}-cooldown:invalidated-at"); |
141 | | - $instance |
142 | | - ->cache() |
143 | | - ->forget("{$cachePrefix}:{$modelClassName}-cooldown:invalidated-at"); |
144 | | - $instance |
145 | | - ->cache() |
146 | | - ->forget("{$cachePrefix}:{$modelClassName}-cooldown:saved-at"); |
147 | | - $instance->flushCache(); |
148 | | - } |
149 | | - |
150 | | - protected function checkCooldownAndFlushAfterPersiting(Model $instance) |
151 | | - { |
152 | | - [$cacheCooldown, $invalidatedAt] = $instance->getModelCacheCooldown($instance); |
153 | | - |
154 | | - if (! $cacheCooldown) { |
155 | | - $instance->flushCache(); |
156 | | - |
157 | | - return; |
158 | | - } |
159 | | - |
160 | | - $this->setCacheCooldownSavedAtTimestamp($instance); |
161 | | - |
162 | | - if (now()->diffInSeconds($invalidatedAt) >= $cacheCooldown) { |
163 | | - $instance->flushCache(); |
164 | | - } |
165 | | - } |
166 | | - |
167 | | - protected function setCacheCooldownSavedAtTimestamp(Model $instance) |
168 | | - { |
169 | | - $cachePrefix = $this->getCachePrefix(); |
170 | | - $modelClassName = get_class($instance); |
171 | | - $cacheKey = "{$cachePrefix}:{$modelClassName}-cooldown:saved-at"; |
172 | | - |
173 | | - $instance->cache() |
174 | | - ->rememberForever($cacheKey, function () { |
175 | | - return now(); |
176 | | - }); |
177 | | - } |
178 | | - |
179 | | - public static function bootCachable() |
180 | | - { |
181 | | - static::saved(function ($instance) { |
182 | | - $instance->checkCooldownAndFlushAfterPersiting($instance); |
183 | | - }); |
184 | | - } |
185 | | - |
186 | | - public static function all($columns = ['*']) |
187 | | - { |
188 | | - if (config('laravel-model-caching.disabled')) { |
189 | | - return parent::all($columns); |
190 | | - } |
191 | | - |
192 | | - $class = get_called_class(); |
193 | | - $instance = new $class; |
194 | | - $tags = [str_slug(get_called_class())]; |
195 | | - $key = $instance->makeCacheKey(); |
196 | | - |
197 | | - return $instance->cache($tags) |
198 | | - ->rememberForever($key, function () use ($columns) { |
199 | | - return parent::all($columns); |
200 | | - }); |
201 | | - } |
202 | | - |
203 | | - public function newEloquentBuilder($query) |
204 | | - { |
205 | | - if (! $this->isCachable()) { |
206 | | - $this->isCachable = true; |
207 | | - |
208 | | - return new EloquentBuilder($query); |
209 | | - } |
210 | | - |
211 | | - return new CachedBuilder($query); |
212 | | - } |
213 | | - |
214 | | - public function isCachable() : bool |
215 | | - { |
216 | | - return $this->isCachable |
217 | | - && ! config('laravel-model-caching.disabled'); |
218 | | - } |
219 | | - |
220 | | - public function scopeWithCacheCooldownSeconds( |
221 | | - EloquentBuilder $query, |
222 | | - int $seconds |
223 | | - ) : EloquentBuilder { |
224 | | - $cachePrefix = $this->getCachePrefix(); |
225 | | - $modelClassName = get_class($this); |
226 | | - $cacheKey = "{$cachePrefix}:{$modelClassName}-cooldown:seconds"; |
227 | | - |
228 | | - $this->cache() |
229 | | - ->rememberForever($cacheKey, function () use ($seconds) { |
230 | | - return $seconds; |
231 | | - }); |
232 | | - |
233 | | - $cacheKey = "{$cachePrefix}:{$modelClassName}-cooldown:invalidated-at"; |
234 | | - $this->cache() |
235 | | - ->rememberForever($cacheKey, function () { |
236 | | - return now(); |
237 | | - }); |
238 | | - |
239 | | - return $query; |
240 | | - } |
| 7 | + use PivotEventTrait; |
| 8 | + use Caching; |
| 9 | + use ModelCaching; |
241 | 10 | } |
0 commit comments