Passed
Push — master ( 9c20ed...2c5d5d )
by Fran
04:30
created

Cache::getDataFromFile()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 6
nc 4
nop 3
dl 0
loc 9
rs 9.6666
c 0
b 0
f 0
ccs 7
cts 7
cp 1
crap 3
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\SingletonTrait;
8
9
/**
10
 * Class Cache
11
 * @package PSFS\base
12
 * Gestión de los ficheros de cache
13
 */
14
class Cache
15
{
16
    /**
17
     * @var \Memcache
18
     */
19
    protected $memcache = null;
20
21
    const JSON = 1;
22
    const TEXT = 2;
23
    const GZIP = 3;
24
    const JSONGZ = 4;
25
    const MEMCACHE = 5;
26
27
    use SingletonTrait;
28
29
    /**
30
     * @return bool
31
     */
32 3
    public static function canUseMemcache()
33
    {
34 3
        return Config::getParam('psfs.memcache', false) && !Config::getParam('debug') && class_exists('Memcached');
35
    }
36
37
    /**
38
     * Método que guarda un text en un fichero
39
     * @param string $data
40
     * @param string $path
41
     * @throws ConfigException
42
     */
43 5 View Code Duplication
    private function saveTextToFile($data, $path)
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...
44
    {
45 5
        GeneratorHelper::createDir(dirname($path));
46 5
        if (false === file_put_contents($path, $data)) {
47
            throw new ConfigException(_('No se tienen los permisos suficientes para escribir en el fichero ') . $path);
48
        }
49 5
    }
50
51
    /**
52
     * Método que extrae el texto de un fichero
53
     * @param string $path
54
     * @param int $transform
55
     * @param boolean $absolute
56
     * @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...
57
     */
58 6
    public function getDataFromFile($path, $transform = Cache::TEXT, $absolute = false)
59
    {
60 6
        $data = null;
61 6
        $absolutePath = ($absolute) ? $path : CACHE_DIR . DIRECTORY_SEPARATOR . $path;
62 6
        if (file_exists($absolutePath)) {
63 4
            $data = file_get_contents($absolutePath);
64 4
        }
65 6
        return Cache::extractDataWithFormat($data, $transform);
66
    }
67
68
    /**
69
     * Método que verifica si un fichero tiene la cache expirada
70
     * @param string $path
71
     * @param int $expires
72
     * @param boolean $absolute
73
     * @return bool
74
     */
75 1
    private function hasExpiredCache($path, $expires = 300, $absolute = false)
76
    {
77 1
        $absolutePath = ($absolute) ? $path : CACHE_DIR . DIRECTORY_SEPARATOR . $path;
78 1
        $lasModificationDate = filemtime($absolutePath);
79 1
        return ($lasModificationDate + $expires <= time());
80
    }
81
82
    /**
83
     * Método que transforma los datos de salida
84
     * @param string $data
85
     * @param int $transform
86
     * @return array|string|null
87
     */
88 6
    public static function extractDataWithFormat($data, $transform = Cache::TEXT)
89
    {
90
        switch ($transform) {
91 6
            case Cache::JSON:
92 6
                $data = json_decode($data, true);
93 6
                break;
94 4
            case Cache::JSONGZ:
95 4
                $data = Cache::extractDataWithFormat($data, Cache::GZIP);
96 4
                $data = Cache::extractDataWithFormat($data, Cache::JSON);
97 4
                break;
98 4
            case Cache::GZIP:
99 4
                if (function_exists('gzuncompress') && !empty($data)) {
100 2
                    $data = @gzuncompress($data ?: '');
101 2
                }
102 4
                break;
103
        }
104 6
        return $data;
105
    }
106
107
    /**
108
     * Método que transforma los datos de entrada del fichero
109
     * @param string $data
110
     * @param int $transform
111
     * @return string
112
     */
113 5
    public static function transformData($data, $transform = Cache::TEXT)
114
    {
115
        switch ($transform) {
116 5
            case Cache::JSON:
117 5
                $data = json_encode($data, JSON_PRETTY_PRINT);
118 5
                break;
119 3
            case Cache::JSONGZ:
120 2
                $data = Cache::transformData($data, Cache::JSON);
121 2
                $data = Cache::transformData($data, Cache::GZIP);
122 2
                break;
123 3
            case Cache::GZIP:
124 2
                if (function_exists('gzcompress')) {
125 2
                    $data = gzcompress($data ?: '');
126 2
                }
127 2
                break;
128
        }
129 5
        return $data;
130
    }
131
132
    /**
133
     * Método que guarda en fichero los datos pasados
134
     * @param $path
135
     * @param $data
136
     * @param int $transform
137
     * @param boolean $absolute
138
     * @param integer $expires
139
     */
140 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...
141
    {
142 5
        $data = Cache::transformData($data, $transform);
143 5
        $absolutePath = ($absolute) ? $path : CACHE_DIR . DIRECTORY_SEPARATOR . $path;
144 5
        $this->saveTextToFile($data, $absolutePath);
145 5
    }
146
147
    /**
148
     * Método que verifica si tiene que leer o no un fichero de cache
149
     * @param string $path
150
     * @param int $expires
151
     * @param callable $function
152
     * @param int $transform
153
     * @return mixed
154
     */
155 1
    public function readFromCache($path, $expires = 300, callable $function, $transform = Cache::TEXT)
156
    {
157 1
        $data = null;
158 1
        if (file_exists(CACHE_DIR . DIRECTORY_SEPARATOR . $path)) {
159 1
            if (null !== $function && $this->hasExpiredCache($path, $expires)) {
160 1
                $data = call_user_func($function);
161 1
                $this->storeData($path, $data, $transform, false, $expires);
162 1
            } else {
163 1
                $data = $this->getDataFromFile($path, $transform);
164
            }
165 1
        }
166 1
        return $data;
167
    }
168
169
    /**
170
     * @return bool
171
     */
172 1
    private static function checkAdminSite()
173
    {
174 1
        $isAdminRequest = false;
175 1
        $lastRequest = Security::getInstance()->getSessionKey("lastRequest");
176 1
        if (null !== $lastRequest) {
177
            $url = str_replace(Request::getInstance()->getRootUrl(true), '', $lastRequest['url']);
178
            $isAdminRequest = preg_match('/^\/admin\//i', $url);
179
        }
180 1
        return (bool)$isAdminRequest;
181
    }
182
183
    /**
184
     * Método estático que revisa si se necesita cachear la respuesta de un servicio o no
185
     * @return integer|boolean
186
     */
187 1
    public static function needCache()
188
    {
189 1
        $needCache = false;
190 1
        if (!self::checkAdminSite()) {
191 1
            $action = Security::getInstance()->getSessionKey("__CACHE__");
192 1
            if (null !== $action && array_key_exists("cache", $action) && $action["cache"] > 0) {
193 1
                $needCache = $action["cache"];
194 1
            }
195 1
        }
196 1
        return $needCache;
197
    }
198
199
    /**
200
     * Método que construye un hash para almacenar la cache
201
     * @return string
202
     */
203 1
    public function getRequestCacheHash()
204
    {
205 1
        $hash = "";
206 1
        $action = Security::getInstance()->getSessionKey("__CACHE__");
207 1
        if (null !== $action && $action["cache"] > 0) {
208 1
            $hash = $action["http"] . " " . $action["slug"];
209 1
        }
210 1
        return sha1($hash);
211
    }
212
}
213