Completed
Push — master ( 2725b3...4f8553 )
by Freek
11s
created

PartialCache   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 192
Duplicated Lines 5.21 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 7
Bugs 2 Features 0
Metric Value
wmc 21
c 7
b 2
f 0
lcom 1
cbo 1
dl 10
loc 192
rs 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 10 1
C cache() 10 32 7
A getCacheKeyForView() 0 10 2
A forget() 0 11 2
A flush() 0 10 3
A renderView() 0 9 3
A getTags() 0 14 3

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
namespace Spatie\PartialCache;
4
5
use Illuminate\Cache\TaggableStore;
6
use Illuminate\Contracts\Cache\Factory as CacheManager;
7
use Illuminate\Contracts\Cache\Repository as Cache;
8
use Illuminate\Contracts\Config\Repository as Config;
9
use Illuminate\Contracts\View\Factory as View;
10
use Spatie\PartialCache\Exceptions\MethodNotSupportedException;
11
12
class PartialCache
13
{
14
    /**
15
     * @var \Illuminate\Contracts\View\Factory
16
     */
17
    protected $view;
18
19
    /**
20
     * @var \Illuminate\Contracts\Cache\Repository
21
     */
22
    protected $cache;
23
24
    /**
25
     * @var \Illuminate\Contracts\Cache\Factory
26
     */
27
    protected $cacheManager;
28
29
    /**
30
     * @var string
31
     */
32
    protected $cacheKey;
33
34
    /**
35
     * @var bool
36
     */
37
    protected $cacheIsTaggable;
38
39
    /**
40
     * @var bool
41
     */
42
    protected $enabled;
43
44
    /**
45
     * @param \Illuminate\Contracts\View\Factory      $view
46
     * @param \Illuminate\Contracts\Cache\Repository  $cache
47
     * @param \Illuminate\Contracts\Cache\Factory     $cacheManager
48
     * @param \Illuminate\Contracts\Config\Repository $config
49
     */
50
    public function __construct(View $view, Cache $cache, CacheManager $cacheManager, Config $config)
51
    {
52
        $this->view = $view;
53
        $this->cache = $cache;
54
        $this->cacheManager = $cacheManager;
55
56
        $this->cacheKey = $config->get('partialcache.key');
57
        $this->cacheIsTaggable = is_a($this->cacheManager->driver()->getStore(), TaggableStore::class);
58
        $this->enabled = $config->get('partialcache.enabled');
59
    }
60
61
    /**
62
     * Cache a view. If minutes are null, the view is cached forever.
63
     *
64
     * @param array        $data
65
     * @param string       $view
66
     * @param array        $mergeData
67
     * @param int          $minutes
68
     * @param string       $key
69
     * @param string|array $tag
70
     *
71
     * @return string
72
     */
73
    public function cache($data, $view, $mergeData = null, $minutes = null, $key = null, $tag = null)
74
    {
75
        if (!$this->enabled) {
76
            return call_user_func($this->renderView($view, $data, $mergeData));
0 ignored issues
show
Bug introduced by
It seems like $mergeData defined by parameter $mergeData on line 73 can also be of type null; however, Spatie\PartialCache\PartialCache::renderView() does only seem to accept array, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
77
        }
78
79
        $viewKey = $this->getCacheKeyForView($view, $key);
80
81
        $mergeData = $mergeData ?: [];
82
83
        $tags = $this->getTags($tag);
84
85 View Code Duplication
        if ($this->cacheIsTaggable && $minutes === null) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
86
            return $this->cache
87
                ->tags($tags)
88
                ->rememberForever($viewKey, $this->renderView($view, $data, $mergeData));
89
        }
90
91 View Code Duplication
        if ($this->cacheIsTaggable) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
92
            return $this->cache
93
                ->tags($tags)
94
                ->remember($viewKey, $minutes, $this->renderView($view, $data, $mergeData));
95
        }
96
97
        if ($minutes === null) {
98
            return $this->cache
99
                ->rememberForever($viewKey, $this->renderView($view, $data, $mergeData));
100
        }
101
102
        return $this->cache
103
            ->remember($viewKey, $minutes, $this->renderView($view, $data, $mergeData));
104
    }
105
106
    /**
107
     * Create a key name for the cached view.
108
     *
109
     * @param string $view
110
     * @param string $key
111
     *
112
     * @return string
113
     */
114
    public function getCacheKeyForView($view, $key = null)
115
    {
116
        $parts = [$this->cacheKey, $view];
117
118
        if ($key !== null) {
119
            $parts[] = $key;
120
        }
121
122
        return implode('.', $parts);
123
    }
124
125
    /**
126
     * Forget a rendered view.
127
     *
128
     * @param string $view
129
     * @param string $key
130
     * @param null|string|array $tag
131
     */
132
    public function forget($view, $key = null, $tag = null)
133
    {
134
        $cacheKey = $this->getCacheKeyForView($view, $key);
135
136
        if ($this->cacheIsTaggable) {
137
            $tags = $this->getTags($tag);
138
            $this->cache->tags($tags)->forget($cacheKey);
139
        }
140
141
        $this->cache->forget($cacheKey);
142
    }
143
144
    /**
145
     * Empty all views linked to a tag or the complete partial cache.
146
     * Note: Only supported by Taggable cache drivers.
147
     *
148
     * @param string $tag
149
     *
150
     * @throws \Spatie\PartialCache\Exceptions\MethodNotSupportedException
151
     */
152
    public function flush($tag = null)
153
    {
154
        if (!$this->cacheIsTaggable) {
155
            throw new MethodNotSupportedException('The cache driver ('.
156
                get_class($this->cacheManager->driver()).') doesn\'t support the flush method.');
157
        }
158
159
        $tag = $tag ?: $this->cacheKey;
160
        $this->cache->tags($tag)->flush();
161
    }
162
163
    /**
164
     * Render a view.
165
     *
166
     * @param string $view
167
     * @param array  $data
168
     * @param array  $mergeData
169
     *
170
     * @return string
171
     */
172
    protected function renderView($view, $data, $mergeData)
173
    {
174
        $data = $data ?: [];
175
        $mergeData = $mergeData ?: [];
176
177
        return function () use ($view, $data, $mergeData) {
178
            return $this->view->make($view, $data, $mergeData)->render();
179
        };
180
    }
181
182
    /**
183
     * Constructs tag array
184
     *
185
     * @param null|string|array $tag
186
     *
187
     * @return array
188
     */
189
    protected function getTags($tag = null)
190
    {
191
        $tags = [$this->cacheKey];
192
193
        if ($tag) {
194
            if (!is_array($tag)) {
195
                $tag = [$tag];
196
            }
197
198
            $tags = array_merge($tags, $tag);
199
        }
200
201
        return $tags;
202
    }
203
}
204