Completed
Push — master ( 680cdf...4de4c2 )
by Abdelrahman
03:41 queued 01:59
created

BaseRepository::enableCacheClear()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 0
loc 6
rs 9.4285
cc 1
eloc 3
nc 1
nop 1
1
<?php
2
3
/*
4
 * NOTICE OF LICENSE
5
 *
6
 * Part of the Rinvex Repository Package.
7
 *
8
 * This source file is subject to The MIT License (MIT)
9
 * that is bundled with this package in the LICENSE file.
10
 *
11
 * Package: Rinvex Repository Package
12
 * License: The MIT License (MIT)
13
 * Link:    https://rinvex.com
14
 */
15
16
namespace Rinvex\Repository\Repositories;
17
18
use Closure;
19
use Illuminate\Contracts\Container\Container;
20
use Rinvex\Repository\Contracts\RepositoryContract;
21
22
abstract class BaseRepository implements RepositoryContract
23
{
24
    /**
25
     * The IoC container instance.
26
     *
27
     * @var \Illuminate\Contracts\Container\Container
28
     */
29
    protected $container;
30
31
    /**
32
     * The repository model.
33
     *
34
     * @var object
35
     */
36
    protected $model;
37
38
    /**
39
     * The repository identifier.
40
     *
41
     * @var string
42
     */
43
    protected $repositoryId;
44
45
    /**
46
     * Indicate if the repository cache is enabled.
47
     *
48
     * @var bool
49
     */
50
    protected $cacheEnabled = true;
51
52
    /**
53
     * Indicate if the repository cache clear is enabled.
54
     *
55
     * @var bool
56
     */
57
    protected $cacheClearEnabled = true;
58
59
    /**
60
     * Execute given callback and cache result set.
61
     *
62
     * @param string   $class
63
     * @param string   $method
64
     * @param string   $hash
65
     * @param \Closure $closure
66
     *
67
     * @return mixed
68
     */
69
    protected function executeCallback($class, $method, $hash, Closure $closure)
70
    {
71
        $cacheKey = $class.'@'.$method.'.'.$hash;
72
        $config   = $this->getContainer('config')->get('rinvex.repository.cache');
73
74
        if ($this->cacheEnabled && $config['lifetime'] && in_array($method, $config['methods']) && ! $this->getContainer('request')->has($config['skip_uri'])) {
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 160 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
75
            if (method_exists($this->getContainer('cache')->getStore(), 'tags')) {
76
                return $config['lifetime'] === -1 ? $this->getContainer('cache')->tags($this->getRepositoryId())->rememberForever($cacheKey, $closure) : $this->getContainer('cache')->tags($this->getRepositoryId())->remember($cacheKey, $config['lifetime'], $closure);
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 266 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
77
            }
78
79
            // Store cache keys by mimicking cache tags
80
            $this->storeCacheKeys($class, $method, $hash, $config['keys_file']);
81
82
            return $config['lifetime'] === -1 ? $this->getContainer('cache')->rememberForever($cacheKey, $closure) : $this->getContainer('cache')->remember($cacheKey, $config['lifetime'], $closure);
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 198 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
83
        }
84
85
        return call_user_func($closure);
86
    }
87
88
    /**
89
     * Set the IoC container instance.
90
     *
91
     * @param \Illuminate\Contracts\Container\Container $container
92
     *
93
     * @return $this
94
     */
95
    public function setContainer(Container $container)
96
    {
97
        $this->container = $container;
98
99
        return $this;
100
    }
101
102
    /**
103
     * Return the IoC container instance or any of it's services.
104
     *
105
     * @param string|null $service
106
     *
107
     * @return mixed
108
     */
109
    public function getContainer($service = null)
110
    {
111
        return is_null($service) ? ($this->container ?: app()) : ($this->container[$service] ?: app($service));
112
    }
113
114
    /**
115
     * Set the repository identifier.
116
     *
117
     * @param string $repositoryId
118
     *
119
     * @return $this
120
     */
121
    public function setRepositoryId($repositoryId)
122
    {
123
        $this->repositoryId = $repositoryId;
124
125
        return $this;
126
    }
127
128
    /**
129
     * Get the repository identifier.
130
     *
131
     * @return string
132
     */
133
    public function getRepositoryId()
134
    {
135
        return $this->repositoryId ?: get_called_class();
136
    }
137
138
    /**
139
     * Enable repository cache.
140
     *
141
     * @param bool $status
142
     *
143
     * @return $this
144
     */
145
    public function enableCache($status = true)
146
    {
147
        $this->cacheEnabled = $status;
148
149
        return $this;
150
    }
151
152
    /**
153
     * Determine if repository cache is enabled.
154
     *
155
     * @return bool
156
     */
157
    public function isCacheEnabled()
158
    {
159
        return $this->cacheEnabled;
160
    }
161
162
    /**
163
     * Enable repository cache clear.
164
     *
165
     * @param bool $status
166
     *
167
     * @return $this
168
     */
169
    public function enableCacheClear($status = true)
170
    {
171
        $this->cacheClearEnabled = $status;
172
173
        return $this;
174
    }
175
176
    /**
177
     * Determine if repository cache clear is enabled.
178
     *
179
     * @return bool
180
     */
181
    public function isCacheClearEnabled()
182
    {
183
        return $this->cacheClearEnabled;
184
    }
185
186
    /**
187
     * Forget the repository cache.
188
     *
189
     * @return $this
190
     */
191
    public function forgetCache()
192
    {
193
        $lifetime = $this->getContainer('config')->get('rinvex.repository.cache.lifetime');
194
195
        if ($this->cacheEnabled && $lifetime) {
196
            if (method_exists($this->getContainer('cache')->getStore(), 'tags')) {
197
                $this->getContainer('cache')->tags($this->getRepositoryId())->flush();
198
            } else {
199
                // Flush cache keys by mimicking cache tags
200
                foreach ($this->flushCacheKeys() as $cacheKey) {
201
                    $this->getContainer('cache')->forget($cacheKey);
202
                }
203
            }
204
205
            $this->getContainer('events')->fire($this->getRepositoryId().'.entity.cache.flushed', [$this]);
206
        }
207
208
        return $this;
209
    }
210
211
    /**
212
     * Set the relationships that should be eager loaded.
213
     *
214
     * @param mixed $relations
215
     *
216
     * @return $this
217
     */
218
    public function with($relations)
219
    {
220
        $this->model = $this->model->with($relations);
221
222
        return $this;
223
    }
224
225
    /**
226
     * Add an "order by" clause to the repository.
227
     *
228
     * @param string $column
229
     * @param string $direction
230
     *
231
     * @return $this
232
     */
233
    public function orderBy($column, $direction = 'asc')
234
    {
235
        $this->model = $this->model->orderBy($column, $direction);
236
237
        return $this;
238
    }
239
240
    /**
241
     * Register a new global scope.
242
     *
243
     * @param \Illuminate\Database\Eloquent\Scope|\Closure|string $scope
244
     * @param \Closure|null                                       $implementation
245
     *
246
     * @throws \InvalidArgumentException
247
     *
248
     * @return mixed
249
     */
250
    public function addGlobalScope($scope, Closure $implementation = null)
251
    {
252
        return $this->model->addGlobalScope($scope, $implementation);
253
    }
254
255
    /**
256
     * Remove all or passed registered global scopes.
257
     *
258
     * @param array|null $scopes
259
     *
260
     * @return $this
261
     */
262
    public function withoutGlobalScopes(array $scopes = null)
263
    {
264
        $this->model = $this->model->withoutGlobalScopes($scopes);
265
266
        return $this;
267
    }
268
269
    /**
270
     * Dynamically pass missing static methods to the model.
271
     *
272
     * @param $method
273
     * @param $parameters
274
     *
275
     * @return mixed
276
     */
277
    public static function __callStatic($method, $parameters)
278
    {
279
        return call_user_func_array([new static(), $method], $parameters);
280
    }
281
282
    /**
283
     * Dynamically pass missing methods to the model.
284
     *
285
     * @param string $method
286
     * @param array  $parameters
287
     *
288
     * @return mixed
289
     */
290
    public function __call($method, $parameters)
291
    {
292
        $model = $this->model;
293
294
        return call_user_func_array([$model, $method], $parameters);
295
    }
296
297
    /**
298
     * Store cache keys by mimicking cache tags.
299
     *
300
     * @param string $class
301
     * @param string $method
302
     * @param string $hash
303
     * @param string $file
304
     *
305
     * @return void
306
     */
307
    protected function storeCacheKeys($class, $method, $hash, $file)
308
    {
309
        $cacheKeys = $this->getCacheKeys($file);
310
311
        if (! isset($cacheKeys[$class]) || ! in_array($method.'.'.$hash, $cacheKeys[$class])) {
312
            $cacheKeys[$class][] = $method.'.'.$hash;
313
            file_put_contents($file, json_encode($cacheKeys));
314
        }
315
    }
316
317
    /**
318
     * Flush cache keys by mimicking cache tags.
319
     *
320
     * @return array
321
     */
322
    protected function flushCacheKeys()
323
    {
324
        $flushedKeys = [];
325
326
        $config    = $this->getContainer('config')->get('rinvex.repository.cache');
327
        $cacheKeys = $this->getCacheKeys($config['keys_file']);
328
329
        if (isset($cacheKeys[get_called_class()]) && is_array($cacheKeys[get_called_class()])) {
330
            foreach ($cacheKeys[get_called_class()] as $cacheKey) {
331
                $flushedKeys[] = $cacheKey;
332
            }
333
334
            unset($cacheKeys[get_called_class()]);
335
            file_put_contents($config['keys_file'], json_encode($cacheKeys));
336
        }
337
338
        return $flushedKeys;
339
    }
340
341
    /**
342
     * Get cache keys file.
343
     *
344
     * @param string $file
345
     *
346
     * @return array
347
     */
348
    protected function getCacheKeys($file)
349
    {
350
        return json_decode(file_get_contents(file_exists($file) ? $file : file_put_contents($file, null)), true) ?: [];
351
    }
352
}
353