Completed
Push — master ( ff2beb...87d779 )
by Renato
08:50
created

CacheableRepository   B

Complexity

Total Complexity 44

Size/Duplication

Total Lines 381
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 79.79%

Importance

Changes 0
Metric Value
dl 0
loc 381
ccs 75
cts 94
cp 0.7979
rs 8.8798
c 0
b 0
f 0
wmc 44
lcom 1
cbo 1

23 Methods

Rating   Name   Duplication   Size   Complexity  
A setCacheRepository() 0 6 1
A getCacheRepository() 0 8 2
A cacheTags() 0 6 2
A skipCache() 0 6 1
A isSkippedCache() 0 12 4
B allowedCache() 0 25 8
A getCacheKey() 0 15 4
A serializeCriteria() 0 10 2
A serializeCriterion() 0 21 3
A getCacheMinutes() 0 6 2
A callCache() 0 14 3
A all() 0 4 1
A paginate() 0 4 1
A find() 0 4 1
A findByField() 0 4 1
A findWhere() 0 4 1
A getByCriteria() 0 4 1
A pluck() 0 4 1
A count() 0 4 1
A max() 0 4 1
A min() 0 4 1
A sum() 0 4 1
A avg() 0 4 1

How to fix   Complexity   

Complex Class

Complex classes like CacheableRepository often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use CacheableRepository, and based on these observations, apply Extract Interface, too.

1
<?php
2
namespace NwLaravel\Repositories\Eloquent;
3
4
use Illuminate\Contracts\Cache\Repository as CacheRepository;
5
use Prettus\Repository\Contracts\CriteriaInterface;
6
use ReflectionObject;
7
use Exception;
8
9
/**
10
 * Class CacheableRepository
11
 */
12
trait CacheableRepository
13
{
14
    /**
15
     * @var CacheRepository
16
     */
17
    protected $cacheRepository = null;
18
19
    /**
20
     * @var boolean
21
     */
22
    protected $cacheSkip = false;
23
24
    /**
25
     * Set Cache Repository
26
     *
27
     * @param CacheRepository $repository
28
     *
29
     * @return $this
30
     */
31 1
    public function setCacheRepository(CacheRepository $repository)
32
    {
33 1
        $this->cacheRepository = $repository;
34
35 1
        return $this;
36
    }
37
38
    /**
39
     * Return instance of Cache Repository
40
     *
41
     * @return CacheRepository
42
     */
43 1
    public function getCacheRepository()
44
    {
45 1
        if (is_null($this->cacheRepository)) {
46 1
            $this->cacheRepository = app(config('repository.cache.repository', 'cache'));
47 1
        }
48
49 1
        return $this->cacheRepository;
50
    }
51
52
    /**
53
     * CacheTags
54
     *
55
     * @param mixed $tags
56
     *
57
     * @return \Illuminate\Cache\TaggedCache
58
     */
59 1
    public function cacheTags($tags = null)
60
    {
61 1
        $tags = empty($tags) ? get_called_class() : $tags;
62
63 1
        return $this->getCacheRepository()->tags($tags);
64
    }
65
66
    /**
67
     * Skip Cache
68
     *
69
     * @param bool $status
70
     *
71
     * @return $this
72
     */
73 1
    public function skipCache($status = true)
74
    {
75 1
        $this->cacheSkip = $status;
76
77 1
        return $this;
78
    }
79
80
    /**
81
     * Is Skipped Cache
82
     *
83
     * @return bool
84
     */
85 2
    public function isSkippedCache()
86
    {
87 2
        $skipped = isset($this->cacheSkip) ? $this->cacheSkip : false;
88 2
        $request = app('Illuminate\Http\Request');
89 2
        $skipCacheParam = config('repository.cache.params.skipCache', 'skipCache');
90
91 2
        if ($request->has($skipCacheParam) && $request->get($skipCacheParam)) {
92 1
            $skipped = true;
93 1
        }
94
95 2
        return $skipped;
96
    }
97
98
    /**
99
     * Allowed Cache
100
     *
101
     * @param string $method
102
     *
103
     * @return bool
104
     */
105 1
    protected function allowedCache($method)
106
    {
107 1
        $cacheEnabled = config('repository.cache.enabled', true);
108
109 1
        if (!$cacheEnabled) {
110
            return false;
111
        }
112
113 1
        $cacheOnly = isset($this->cacheOnly) ? $this->cacheOnly : config('repository.cache.allowed.only', null);
0 ignored issues
show
Bug introduced by
The property cacheOnly does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
114 1
        $cacheExcept = isset($this->cacheExcept) ? $this->cacheExcept : config('repository.cache.allowed.except', null);
0 ignored issues
show
Bug introduced by
The property cacheExcept does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
115
116 1
        if (is_array($cacheOnly)) {
117
            return in_array($method, $cacheOnly);
118
        }
119
120 1
        if (is_array($cacheExcept)) {
121
            return !in_array($method, $cacheExcept);
122
        }
123
124 1
        if (is_null($cacheOnly) && is_null($cacheExcept)) {
125 1
            return true;
126
        }
127
128
        return false;
129
    }
130
131
    /**
132
     * Get Cache key for the method
133
     *
134
     * @param string $method
135
     * @param array  $args
136
     *
137
     * @return string
138
     */
139 1
    public function getCacheKey($method, $args = null)
140
    {
141 1
        $request = app('Illuminate\Http\Request');
142 1
        $args = serialize($args);
143 1
        $criteria = $this->serializeCriteria();
144 1
        $sql = $this->model->toSql();
0 ignored issues
show
Bug introduced by
The property model does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
Unused Code introduced by
$sql is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
145 1
        $bindings = serialize($this->model->getBindings());
146 1
        $skipPresenter = $this->skipPresenter ? '-skipPresenter-' : '';
0 ignored issues
show
Bug introduced by
The property skipPresenter does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
147
        $url = '';
148 1
        if ($method == 'paginate' || $method == 'search') {
149
            $url = $request->fullUrl();
150
        }
151
152
        return sprintf('%s@%s-%s', get_called_class(), $method, md5($args . $criteria . $bindings . $skipPresenter . $url));
153
    }
154
155
    /**
156 1
     * Serialize the criteria making sure the Closures are taken care of.
157
     *
158
     * @return string
159 1
     */
160
    protected function serializeCriteria()
161
    {
162
        try {
163
            return serialize($this->getCriteria());
0 ignored issues
show
Bug introduced by
The method getCriteria() does not exist on NwLaravel\Repositories\E...ent\CacheableRepository. Did you maybe mean getByCriteria()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
164
        } catch (Exception $e) {
165
            return serialize($this->getCriteria()->map(function ($criterion) {
0 ignored issues
show
Bug introduced by
The method getCriteria() does not exist on NwLaravel\Repositories\E...ent\CacheableRepository. Did you maybe mean getByCriteria()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
166
                return $this->serializeCriterion($criterion);
167
            }));
168
        }
169
    }
170
171
    /**
172
     * Serialize single criterion with customized serialization of Closures.
173
     *
174
     * @param  \Prettus\Repository\Contracts\CriteriaInterface $criterion
175
     *
176
     * @return \Prettus\Repository\Contracts\CriteriaInterface|array
177
     *
178
     * @throws \Exception
179
     */
180
    protected function serializeCriterion($criterion)
181
    {
182
        try {
183
            serialize($criterion);
184
185
            return $criterion;
186
        } catch (Exception $e) {
187
            // We want to take care of the closure serialization errors,
188
            // other than that we will simply re-throw the exception.
189
            if ($e->getMessage() !== "Serialization of 'Closure' is not allowed") {
190
                throw $e;
191
            }
192
193
            $reflection = new ReflectionObject($criterion);
194
195
            return [
196
                'hash' => md5((string) $reflection),
197
                'properties' => $reflection->getProperties(),
198
            ];
199
        }
200
    }
201
202
    /**
203 1
     * Get cache minutes
204
     *
205 1
     * @return int
206
     */
207 1
    public function getCacheMinutes()
208
    {
209
        $cacheMinutes = isset($this->cacheMinutes) ? $this->cacheMinutes : config('repository.cache.minutes', 30);
0 ignored issues
show
Bug introduced by
The property cacheMinutes does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
210
211
        return $cacheMinutes;
212
    }
213
214
    /**
215
     * call Cache
216
     *
217
     * @param string $method
218 1
     * @param array  $args
219
     *
220 1
     * @return mixed
221
     */
222
    public function callCache($method, array $args)
223
    {
224 1
        if (!$this->allowedCache($method) || $this->isSkippedCache()) {
225 1
            return call_user_func_array(['parent', $method], $args);
226 1
        }
227
228 1
        $key = $this->getCacheKey($method, $args);
229
        $minutes = $this->getCacheMinutes();
230 1
        $value = $this->cacheTags()->remember($key, $minutes, function () use ($method, $args) {
231
            return call_user_func_array(['parent', $method], $args);
232
        });
233
234
        return $value;
235
    }
236
237
    /**
238
     * Retrieve all data of repository
239
     *
240 1
     * @param array $columns
241
     *
242 1
     * @return mixed
243
     */
244
    public function all($columns = ['*'])
0 ignored issues
show
Unused Code introduced by
The parameter $columns is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
245
    {
246
        return $this->callCache(__FUNCTION__, func_get_args());
247
    }
248
249
    /**
250
     * Retrieve all data of repository, paginated
251
     *
252
     * @param null $limit
253
     * @param array $columns
254 1
     * @param string $method
255
     *
256 1
     * @return mixed
257
     */
258
    public function paginate($limit = null, $columns = ['*'], $method = "paginate")
0 ignored issues
show
Unused Code introduced by
The parameter $limit is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $columns is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $method is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
259
    {
260
        return $this->callCache(__FUNCTION__, func_get_args());
261
    }
262
263
    /**
264
     * Find data by id
265
     *
266
     * @param int   $id
267 1
     * @param array $columns
268
     *
269 1
     * @return mixed
270
     */
271
    public function find($id, $columns = ['*'])
0 ignored issues
show
Unused Code introduced by
The parameter $id is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $columns is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
272
    {
273
        return $this->callCache(__FUNCTION__, func_get_args());
274
    }
275
276
    /**
277
     * Find data by field and value
278
     *
279
     * @param string $field
280
     * @param mixed  $value
281 1
     * @param array  $columns
282
     *
283 1
     * @return mixed
284
     */
285
    public function findByField($field, $value = null, $columns = ['*'])
0 ignored issues
show
Unused Code introduced by
The parameter $columns is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $field is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $value is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
286
    {
287
        return $this->callCache(__FUNCTION__, func_get_args());
288
    }
289
290
    /**
291
     * Find data by multiple fields
292
     *
293
     * @param array $where
294 1
     * @param array $columns
295
     *
296 1
     * @return mixed
297
     */
298
    public function findWhere(array $where, $columns = ['*'])
0 ignored issues
show
Unused Code introduced by
The parameter $columns is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $where is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
299
    {
300
        return $this->callCache(__FUNCTION__, func_get_args());
301
    }
302
303
    /**
304
     * Find data by Criteria
305
     *
306 1
     * @param CriteriaInterface $criteria
307
     *
308 1
     * @return mixed
309
     */
310
    public function getByCriteria(CriteriaInterface $criteria)
0 ignored issues
show
Unused Code introduced by
The parameter $criteria is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
311
    {
312
        return $this->callCache(__FUNCTION__, func_get_args());
313
    }
314
315
    /**
316
     * Pluck
317
     *
318
     * @param string $column
319 1
     * @param array  $key
320
     *
321 1
     * @return array
322
     */
323
    public function pluck($column, $key = null)
0 ignored issues
show
Unused Code introduced by
The parameter $column is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $key is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
324
    {
325
        return $this->callCache(__FUNCTION__, func_get_args());
326
    }
327
328
    /**
329
     * Count results of repository
330
     *
331
     * @param array  $where
332 1
     * @param string $columns
333
     *
334 1
     * @return int
335
     */
336
    public function count(array $where = [], $columns = '*')
0 ignored issues
show
Unused Code introduced by
The parameter $where is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $columns is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
337
    {
338
        return $this->callCache(__FUNCTION__, func_get_args());
339
    }
340
341
    /**
342
     * Max
343
     *
344
     * @param mixed $field Mixed Field
345 1
     * @param array $input Array Input
346
     *
347 1
     * @return mixed
348
     */
349
    public function max($field, array $input = array())
0 ignored issues
show
Unused Code introduced by
The parameter $field is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $input is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
350
    {
351
        return $this->callCache(__FUNCTION__, func_get_args());
352
    }
353
354
    /**
355
     * Min
356
     *
357
     * @param mixed $field Mixed Field
358 1
     * @param array $input Array Input
359
     *
360 1
     * @return mixed
361
     */
362
    public function min($field, array $input = array())
0 ignored issues
show
Unused Code introduced by
The parameter $field is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $input is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
363
    {
364
        return $this->callCache(__FUNCTION__, func_get_args());
365
    }
366
367
    /**
368
     * Sum
369
     *
370
     * @param mixed $field Mixed Field
371 1
     * @param array $input Array Input
372
     *
373 1
     * @return float
374
     */
375
    public function sum($field, array $input = array())
0 ignored issues
show
Unused Code introduced by
The parameter $input is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $field is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
376
    {
377
        return $this->callCache(__FUNCTION__, func_get_args());
378
    }
379
380
    /**
381
     * Average
382
     *
383
     * @param mixed $field Mixed Field
384 1
     * @param array $input Array Input
385
     *
386 1
     * @return float
387
     */
388
    public function avg($field, array $input = array())
0 ignored issues
show
Unused Code introduced by
The parameter $input is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $field is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
389
    {
390
        return $this->callCache(__FUNCTION__, func_get_args());
391
    }
392
}
393