Passed
Push — master ( 5b4546...2dd92a )
by Fran
09:27
created

Cache   B

Complexity

Total Complexity 40

Size/Duplication

Total Lines 206
Duplicated Lines 3.4 %

Coupling/Cohesion

Components 1
Dependencies 7

Test Coverage

Coverage 93.1%

Importance

Changes 0
Metric Value
dl 7
loc 206
ccs 81
cts 87
cp 0.931
rs 8.2608
c 0
b 0
f 0
wmc 40
lcom 1
cbo 7

12 Methods

Rating   Name   Duplication   Size   Complexity  
A canUseMemcache() 0 4 3
A saveTextToFile() 7 7 2
A getDataFromFile() 0 9 3
A hasExpiredCache() 0 6 2
B extractDataWithFormat() 0 18 7
B transformData() 0 18 6
A storeData() 0 6 2
A readFromCache() 0 13 4
A checkAdminSite() 0 4 1
B needCache() 0 11 6
A getRequestCacheHash() 0 12 3
A flushCache() 0 6 1

How to fix   Duplicated Code    Complexity   

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:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Cache 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 Cache, and based on these observations, apply Extract Interface, too.

1
<?php
2
namespace PSFS\base;
3
4
use PSFS\base\config\Config;
5
use PSFS\base\exception\ConfigException;
6
use PSFS\base\types\helpers\GeneratorHelper;
7
use PSFS\base\types\helpers\FileHelper;
8
use PSFS\base\types\traits\SingletonTrait;
9
10
/**
11
 * Class Cache
12
 * @package PSFS\base
13
 * Gestión de los ficheros de cache
14
 */
15
class Cache
16
{
17
    /**
18
     * @var \Memcache
19
     */
20
    protected $memcache = null;
21
22
    const JSON = 1;
23
    const TEXT = 2;
24
    const GZIP = 3;
25
    const JSONGZ = 4;
26
    const MEMCACHE = 5;
27
28
    use SingletonTrait;
29
30
    /**
31
     * @return bool
32
     */
33 3
    public static function canUseMemcache()
34
    {
35 3
        return Config::getParam('psfs.memcache', false) && !Config::getParam('debug') && class_exists('Memcached');
36
    }
37
38
    /**
39
     * Método que guarda un text en un fichero
40
     * @param string $data
41
     * @param string $path
42
     * @throws ConfigException
43
     */
44 5 View Code Duplication
    private function saveTextToFile($data, $path)
45
    {
46 5
        GeneratorHelper::createDir(dirname($path));
47 5
        if (false === FileHelper::writeFile($path, $data)) {
48
            throw new ConfigException(_('No se tienen los permisos suficientes para escribir en el fichero ') . $path);
49
        }
50 5
    }
51
52
    /**
53
     * Método que extrae el texto de un fichero
54
     * @param string $path
55
     * @param int $transform
56
     * @param boolean $absolute
57
     * @return mixed
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use array|string|null.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
58
     */
59 8
    public function getDataFromFile($path, $transform = Cache::TEXT, $absolute = false)
60
    {
61 8
        $data = null;
62 8
        $absolutePath = ($absolute) ? $path : CACHE_DIR . DIRECTORY_SEPARATOR . $path;
63 8
        if (file_exists($absolutePath)) {
64 5
            $data = FileHelper::readFile($absolutePath);
65 5
        }
66 8
        return Cache::extractDataWithFormat($data, $transform);
67
    }
68
69
    /**
70
     * Método que verifica si un fichero tiene la cache expirada
71
     * @param string $path
72
     * @param int $expires
73
     * @param boolean $absolute
74
     * @return bool
75
     */
76 1
    private function hasExpiredCache($path, $expires = 300, $absolute = false)
77
    {
78 1
        $absolutePath = ($absolute) ? $path : CACHE_DIR . DIRECTORY_SEPARATOR . $path;
79 1
        $lasModificationDate = filemtime($absolutePath);
80 1
        return ($lasModificationDate + $expires <= time());
81
    }
82
83
    /**
84
     * Método que transforma los datos de salida
85
     * @param string $data
86
     * @param int $transform
87
     * @return array|string|null
88
     */
89 8
    public static function extractDataWithFormat($data, $transform = Cache::TEXT)
90
    {
91
        switch ($transform) {
92 8
            case Cache::JSON:
93 8
                $data = json_decode($data, true);
94 8
                break;
95 5
            case Cache::JSONGZ:
96 5
                $data = Cache::extractDataWithFormat($data, Cache::GZIP);
97 5
                $data = Cache::extractDataWithFormat($data, Cache::JSON);
98 5
                break;
99 5
            case Cache::GZIP:
100 5
                if (function_exists('gzuncompress') && !empty($data)) {
101 2
                    $data = @gzuncompress($data ?: '');
102 2
                }
103 5
                break;
104
        }
105 8
        return $data;
106
    }
107
108
    /**
109
     * Método que transforma los datos de entrada del fichero
110
     * @param string $data
111
     * @param int $transform
112
     * @return string
113
     */
114 5
    public static function transformData($data, $transform = Cache::TEXT)
115
    {
116
        switch ($transform) {
117 5
            case Cache::JSON:
118 5
                $data = json_encode($data, JSON_PRETTY_PRINT);
119 5
                break;
120 3
            case Cache::JSONGZ:
121 2
                $data = Cache::transformData($data, Cache::JSON);
122 2
                $data = Cache::transformData($data, Cache::GZIP);
123 2
                break;
124 3
            case Cache::GZIP:
125 2
                if (function_exists('gzcompress')) {
126 2
                    $data = gzcompress($data ?: '');
127 2
                }
128 2
                break;
129
        }
130 5
        return $data;
131
    }
132
133
    /**
134
     * Método que guarda en fichero los datos pasados
135
     * @param $path
136
     * @param $data
137
     * @param int $transform
138
     * @param boolean $absolute
139
     * @param integer $expires
140
     */
141 5
    public function storeData($path, $data, $transform = Cache::TEXT, $absolute = false, $expires = 600)
0 ignored issues
show
Unused Code introduced by
The parameter $expires 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...
142
    {
143 5
        $data = Cache::transformData($data, $transform);
144 5
        $absolutePath = ($absolute) ? $path : CACHE_DIR . DIRECTORY_SEPARATOR . $path;
145 5
        $this->saveTextToFile($data, $absolutePath);
146 5
    }
147
148
    /**
149
     * Método que verifica si tiene que leer o no un fichero de cache
150
     * @param string $path
151
     * @param int $expires
152
     * @param callable $function
153
     * @param int $transform
154
     * @return mixed
155
     */
156 1
    public function readFromCache($path, $expires = 300, callable $function, $transform = Cache::TEXT)
157
    {
158 1
        $data = null;
159 1
        if (file_exists(CACHE_DIR . DIRECTORY_SEPARATOR . $path)) {
160 1
            if (null !== $function && $this->hasExpiredCache($path, $expires)) {
161 1
                $data = call_user_func($function);
162 1
                $this->storeData($path, $data, $transform, false, $expires);
163 1
            } else {
164 1
                $data = $this->getDataFromFile($path, $transform);
165
            }
166 1
        }
167 1
        return $data;
168
    }
169
170
    /**
171
     * @return bool
172
     */
173 1
    private static function checkAdminSite()
174
    {
175 1
        return Security::getInstance()->canAccessRestrictedAdmin();
176
    }
177
178
    /**
179
     * Método estático que revisa si se necesita cachear la respuesta de un servicio o no
180
     * @return integer|boolean
181
     */
182 1
    public static function needCache()
183
    {
184 1
        $needCache = false;
185 1
        if (!self::checkAdminSite() && !Config::getParam('debug')) {
186 1
            $action = Security::getInstance()->getSessionKey("__CACHE__");
187 1
            if (null !== $action && array_key_exists("cache", $action) && $action["cache"] > 0) {
188 1
                $needCache = $action["cache"];
189 1
            }
190 1
        }
191 1
        return $needCache;
192
    }
193
194
    /**
195
     * Método que construye un hash para almacenar la cache
196
     * @return array
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use array<string|null>.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
197
     */
198 1
    public function getRequestCacheHash()
199
    {
200 1
        $hashPath = null;
201 1
        $filename = null;
202 1
        $action = Security::getInstance()->getSessionKey("__CACHE__");
203 1
        if (null !== $action && $action["cache"] > 0) {
204 1
            $query = Request::getInstance()->getQueryParams();
205 1
            $filename = FileHelper::generateHashFilename($action["http"], $action["slug"], $query);
206 1
            $hashPath = FileHelper::generateCachePath($action, $query);
207 1
        }
208 1
        return [$hashPath, $filename];
209
    }
210
211
    /**
212
     * Flush cache when save a registry
213
     */
214
    public function flushCache() {
215
        $action = Security::getInstance()->getSessionKey("__CACHE__");
216
        $query = Request::getInstance()->getQueryParams();
217
        $hashPath = FileHelper::generateCachePath($action, $query);
218
219
    }
220
}
221