Completed
Push — master ( 375fff...680cdf )
by Abdelrahman
02:40
created

BaseRepository::storeCacheKeys()   B

Complexity

Conditions 5
Paths 4

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 0
loc 9
rs 8.8571
cc 5
eloc 5
nc 4
nop 4
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 string
35
     */
36
    protected $model;
37
38
    /**
39
     * The repository identifier.
40
     *
41
     * @var string
42
     */
43
    protected $repositoryId;
44
45
    /**
46
     * The repository cache status.
47
     *
48
     * @var bool
49
     */
50
    protected $cacheEnabled = true;
51
52
    /**
53
     * The repository cache clear status.
54
     *
55
     * @var bool
56
     */
57
    protected $cacheClear = true;
58
59
    /**
60
     * Execute given callback and cache result set.
61
     *
62
     * @param string   $class
63
     * @param string   $method
64
     * @param string   $cacheKey
0 ignored issues
show
Bug introduced by
There is no parameter named $cacheKey. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
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);
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 $service
0 ignored issues
show
Documentation introduced by
Should the type for parameter $service not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
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
     * Set the repository cache status.
140
     *
141
     * @param bool $status
142
     *
143
     * @return $this
144
     */
145
    public function setCacheStatus($status)
146
    {
147
        $this->cacheEnabled = (bool) $status;
148
149
        return $this;
150
    }
151
152
    /**
153
     * Get the repository cache status.
154
     *
155
     * @return bool
156
     */
157
    public function getCacheStatus()
158
    {
159
        return $this->cacheEnabled;
160
    }
161
162
    /**
163
     * Set the repository cache clear status.
164
     *
165
     * @param bool $status
166
     *
167
     * @return $this
168
     */
169
    public function setCacheClearStatus($status)
170
    {
171
        $this->cacheClear = (bool) $status;
172
173
        return $this;
174
    }
175
176
    /**
177
     * Get the repository cache clear status.
178
     *
179
     * @return bool
180
     */
181
    public function getCacheClearStatus()
182
    {
183
        return $this->cacheClear;
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);
0 ignored issues
show
Bug introduced by
The method with cannot be called on $this->model (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
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);
0 ignored issues
show
Bug introduced by
The method orderBy cannot be called on $this->model (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
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);
0 ignored issues
show
Bug introduced by
The method addGlobalScope cannot be called on $this->model (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
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);
0 ignored issues
show
Bug introduced by
The method withoutGlobalScopes cannot be called on $this->model (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
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 $class
301
     * @param $method
302
     * @param $hash
303
     * @param $config
304
     *
305
     * @return void
306
     */
307
    protected function storeCacheKeys($class, $method, $hash, $config)
308
    {
309
        $cacheKeys = json_decode(file_get_contents(file_exists($config['keys_file']) ? $config['keys_file'] : file_put_contents($config['keys_file'], null)), true) ?: [];
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 170 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...
310
311
        if (! isset($cacheKeys[$class]) || ! in_array($method.'.'.$hash, $cacheKeys[$class])) {
312
            $cacheKeys[$class][] = $method.'.'.$hash;
313
            file_put_contents($config['keys_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 = json_decode(file_get_contents(file_exists($config['keys_file']) ? $config['keys_file'] : file_put_contents($config['keys_file'], null)), true) ?: [];
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 170 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...
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