Completed
Push — 2.0 ( aed067...b26523 )
by Marco
04:31
created

AbstractFilesystemProvider   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 243
Duplicated Lines 41.15 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 37.04%

Importance

Changes 2
Bugs 1 Features 0
Metric Value
wmc 22
c 2
b 1
f 0
lcom 1
cbo 4
dl 100
loc 243
ccs 30
cts 81
cp 0.3704
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
B __construct() 0 23 6
B setXattr() 0 31 3
B setGhost() 0 33 3
B getXattr() 49 49 5
B getGhost() 51 51 5

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 namespace Comodojo\Cache\Providers;
2
3
use \Comodojo\Cache\Components\FileSystemTools;
4
use \Psr\Log\LoggerInterface;
5
use \Comodojo\Exception\CacheException;
6
use \Exception;
7
8
/**
9
 * File cache class
10
 *
11
 * @package     Comodojo Spare Parts
12
 * @author      Marco Giovinazzi <[email protected]>
13
 * @license     MIT
14
 *
15
 * LICENSE:
16
 *
17
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
 * THE SOFTWARE.
24
 */
25
26
abstract class AbstractFilesystemProvider extends AbstractProvider {
27
28
    /**
29
     * Current cache folder
30
     *
31
     * @var string
32
     */
33
    protected $cache_folder;
34
35
    protected $xattr_support = false;
36
37
    /**
38
     * Class constructor
39
     *
40
     * @throws CacheException
41
     */
42 18
    public function __construct($cache_folder, LoggerInterface $logger = null) {
43
44 18
        if ( empty($cache_folder) || !is_string($cache_folder) ) {
45
46
            throw new CacheException("Invalid or unspecified cache folder");
47
48
        }
49
50 18
        parent::__construct($logger);
51
52 18
        $this->cache_folder = $cache_folder[strlen($cache_folder) - 1] == "/" ? $cache_folder : ($cache_folder."/");
53
54 18
        if ( FileSystemTools::checkCacheFolder($this->cache_folder) === false ) {
55
56
            $this->logger->error("Cache folder $cache_folder is not writeable, disabling cache administratively");
57
58
            $this->disable();
59
60
        }
61
62 18
        $this->xattr_support = FileSystemTools::checkXattrSupport() && FileSystemTools::checkXattrFilesystemSupport($this->cache_folder);
63
64 18
    }
65
66
    /**
67
     * Set a cache element using xattr
68
     *
69
     * @param   string  $name    Name for cache element
70
     * @param   mixed   $data    Data to cache
71
     * @param   int     $ttl     Time to live
72
     *
73
     * @return  bool
74
     */
75
    protected function setXattr($name, $data, $ttl) {
76
77
        $cacheFile = $name.".cache";
78
79
        $cached = file_put_contents($cacheFile, $data, LOCK_EX);
80
81
        if ( $cached === false ) {
82
83
            $this->logger->error("Error writing cache object $cacheFile, exiting gracefully", pathinfo($cacheFile));
84
85
            $this->setErrorState("Error writing cache object $cacheFile");
86
87
            return false;
88
89
        }
90
91
        $tagged = xattr_set($cacheFile, "EXPIRE", $ttl, XATTR_DONTFOLLOW);
92
93
        if ( $tagged === false ) {
94
95
            $this->logger->error("Error writing cache ttl cacheFile (XATTR), exiting gracefully", pathinfo($cacheFile));
96
97
            $this->setErrorState("Error writing cache ttl cacheFile (XATTR)");
98
99
            return false;
100
101
        }
102
103
        return true;
104
105
    }
106
107
    /**
108
     * Set a cache element using ghost file
109
     *
110
     * @param   string  $name    Name for cache element
111
     * @param   mixed   $data    Data to cache
112
     * @param   int     $ttl     Time to live
113
     *
114
     * @return  bool
115
     */
116 33
    protected function setGhost($name, $data, $ttl) {
117
118 33
        $cacheFile = $name.".cache";
119
120 33
        $cacheGhost = $name.".expire";
121
122 33
        $cached = file_put_contents($cacheFile, $data, LOCK_EX);
123
124 33
        if ( $cached === false ) {
125
126
            $this->logger->error("Error writing cache object $cacheFile, exiting gracefully", pathinfo($cacheFile));
127
128
            $this->setErrorState("Error writing cache object $cacheFile");
129
130
            return false;
131
132
        }
133
134 33
        $tagged = file_put_contents($cacheGhost, $ttl, LOCK_EX);
135
136 33
        if ( $tagged === false ) {
137
138
            $this->logger->error("Error writing cache ttl cacheGhost (GHOST), exiting gracefully", pathinfo($cacheGhost));
139
140
            $this->setErrorState("Error writing cache ttl cacheGhost (GHOST)");
141
142
            return false;
143
144
        }
145
146 33
        return true;
147
148
    }
149
150
    /**
151
     * Get a cache element using xattr
152
     *
153
     * @param   string  $name    Name for cache element
154
     * @param   int     $time
155
     *
156
     * @return  mixed
157
     */
158 View Code Duplication
    protected function getXattr($name, $time) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
159
160
        $cacheFile = $name.".cache";
161
162
        if ( file_exists($cacheFile) ) {
163
164
            $expire = xattr_get($cacheFile, "EXPIRE", XATTR_DONTFOLLOW);
165
166
            if ( $expire === false ) {
167
168
                $this->logger->error("Error reading cache ttl $cacheFile (XATTR), exiting gracefully", pathinfo($cacheFile));
169
170
                $this->setErrorState("Error reading cache ttl $cacheFile (XATTR)");
171
172
                $return = null;
173
174
            } else if ( $expire < $time ) {
175
176
                $return = null;
177
178
            } else {
179
180
                $data = file_get_contents($cacheFile);
181
182
                if ( $data === false ) {
183
184
                    $this->logger->error("Error reading cache content $cacheFile, exiting gracefully", pathinfo($cacheFile));
185
186
                    $this->setErrorState("Error reading cache content $cacheFile");
187
188
                    $return = null;
189
190
                } else {
191
192
                    $return = $data;
193
194
                }
195
196
            }
197
198
        } else {
199
200
            $return = null;
201
202
        }
203
204
        return $return;
205
206
    }
207
208
    /**
209
     * Get a cache element using ghost file
210
     *
211
     * @param   string  $name    Name for cache element
212
     * @param   int     $time
213
     *
214
     * @return  mixed
215
     */
216 20 View Code Duplication
    protected function getGhost($name, $time) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
217
218 20
        $cacheFile = $name.".cache";
219
220 20
        $cacheGhost = $name.".expire";
221
222 20
        if ( file_exists($cacheFile) ) {
223
224 13
            $expire = file_get_contents($cacheGhost);
225
226 13
            if ( $expire === false ) {
227
228
                $this->logger->error("Error reading cache ttl $cacheGhost (GHOST), exiting gracefully", pathinfo($cacheGhost));
229
230
                $this->setErrorState("Error reading cache ttl $cacheGhost (GHOST)");
231
232
                $return = null;
233
234 13
            } else if ( intval($expire) < $time ) {
235
236 3
                $return = null;
237
238 3
            } else {
239
240 10
                $data = file_get_contents($cacheFile);
241
242 10
                if ( $data === false ) {
243
244
                    $this->logger->error("Error reading cache content $cacheFile, exiting gracefully", pathinfo($cacheFile));
245
246
                    $this->setErrorState("Error reading cache content $cacheFile");
247
248
                    $return = null;
249
250
                } else {
251
252 10
                    $return = $data;
253
254
                }
255
256
            }
257
258 13
        } else {
259
260 9
            $return = null;
261
262
        }
263
264 20
        return $return;
265
266
    }
267
268
}
269