Test Failed
Push — master ( 1b7368...050678 )
by Fran
25:16 queued 22:49
created

Cache::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
namespace PSFS\base;
3
4
use PSFS\base\config\Config;
5
use PSFS\base\exception\ConfigException;
6
use PSFS\base\exception\GeneratorException;
7
use PSFS\base\types\Api;
8
use PSFS\base\types\helpers\FileHelper;
9
use PSFS\base\types\helpers\GeneratorHelper;
10
use PSFS\base\types\helpers\Inspector;
11
use PSFS\base\types\traits\SingletonTrait;
12
13
/**
14
 * Class Cache
15
 * @package PSFS\base
16
 * Gestión de los ficheros de cache
17
 */
18
class Cache
19
{
20
    /**
21
     * @var \Memcache
22
     */
23
    protected $memcache = null;
24
25
    const JSON = 1;
26
    const TEXT = 2;
27
    const GZIP = 3;
28
    const JSONGZ = 4;
29
    const MEMCACHE = 5;
30
31
    const CACHE_SESSION_VAR = '__CACHE__';
32
33
    use SingletonTrait;
34
35 2
    public function __construct()
36
    {
37 2
        $this->setLoaded(true);
38
    }
39
40
    /**
41
     * @return bool
42
     */
43 5
    public static function canUseMemcache()
44
    {
45 5
        return Config::getParam('psfs.memcache', false) && !Config::getParam('debug') && class_exists('Memcached');
46
    }
47
48
    /**
49
     * @param string $data
50
     * @param string $path
51
     * @throws GeneratorException
52
     * @throws ConfigException
53
     */
54 14
    private function saveTextToFile($data, $path)
55
    {
56 14
        GeneratorHelper::createDir(dirname($path));
57 14
        if (false === FileHelper::writeFile($path, $data)) {
0 ignored issues
show
introduced by
The condition false === PSFS\base\type...writeFile($path, $data) is always false.
Loading history...
58
            throw new ConfigException(t('No se tienen los permisos suficientes para escribir en el fichero ') . $path);
59
        }
60
    }
61
62
    /**
63
     * @param string $path
64
     * @param int $transform
65
     * @param boolean $absolute
66
     * @return mixed
67
     */
68 16
    public function getDataFromFile($path, $transform = Cache::TEXT, $absolute = false)
69
    {
70 16
        Inspector::stats('[Cache] Gathering data from cache', Inspector::SCOPE_DEBUG);
71 16
        $data = null;
72 16
        $absolutePath = $absolute ? $path : CACHE_DIR . DIRECTORY_SEPARATOR . $path;
73 16
        if (file_exists($absolutePath)) {
74 11
            $data = FileHelper::readFile($absolutePath);
75
        }
76 16
        return self::extractDataWithFormat($data, $transform);
77
    }
78
79
    /**
80
     * @param string $path
81
     * @param int $expires
82
     * @param boolean $absolute
83
     * @return bool
84
     */
85 1
    private function hasExpiredCache($path, $expires = 300, $absolute = false)
86
    {
87 1
        Inspector::stats('[Cache] Checking expiration', Inspector::SCOPE_DEBUG);
88 1
        $absolutePath = ($absolute) ? $path : CACHE_DIR . DIRECTORY_SEPARATOR . $path;
89 1
        $lasModificationDate = filemtime($absolutePath);
90 1
        return ($lasModificationDate + $expires <= time());
91
    }
92
93
    /**
94
     * @param mixed $data
95
     * @param int $transform
96
     * @return mixed
97
     */
98 16
    public static function extractDataWithFormat($data = null, $transform = Cache::TEXT)
99
    {
100 16
        Inspector::stats('[Cache] Extracting data from cache', Inspector::SCOPE_DEBUG);
101
        switch ($transform) {
102
            case self::JSON:
103 16
                $data = json_decode($data ?: '', true);
104 16
                break;
105
            case self::JSONGZ:
106 4
                $data = self::extractDataWithFormat($data, self::GZIP);
107 4
                $data = self::extractDataWithFormat($data, self::JSON);
108 4
                break;
109
            case self::GZIP:
110 4
                if (null !== $data && function_exists('gzuncompress')) {
111 3
                    $data = @gzuncompress($data ?: '');
112
                }
113 4
                break;
114
        }
115 16
        return $data;
116
    }
117
118
    /**
119
     * @param string $data
120
     * @param int $transform
121
     * @return string
122
     */
123 14
    public static function transformData($data, $transform = Cache::TEXT)
124
    {
125 14
        Logger::log('Transform data in cache', LOG_DEBUG);
126
        switch ($transform) {
127
            case self::JSON:
128 13
                $data = json_encode($data, JSON_PRETTY_PRINT);
129 13
                break;
130
            case self::JSONGZ:
131 3
                $data = self::transformData($data, self::JSON);
132 3
                $data = self::transformData($data, self::GZIP);
133 3
                break;
134
            case self::GZIP:
135 3
                if (function_exists('gzcompress')) {
136 3
                    $data = gzcompress($data ?: '');
137
                }
138 3
                break;
139
        }
140 14
        return $data;
141
    }
142
143
    /**
144
     * @param string $path
145
     * @param mixed $data
146
     * @param int $transform
147
     * @param bool $absolute
148
     * @throws GeneratorException
149
     * @throws ConfigException
150
     */
151 14
    public function storeData($path, $data, $transform = Cache::TEXT, $absolute = false)
152
    {
153 14
        Inspector::stats('[Cache] Store data in cache', Inspector::SCOPE_DEBUG);
154 14
        $data = self::transformData($data, $transform);
155 14
        $absolutePath = $absolute ? $path : CACHE_DIR . DIRECTORY_SEPARATOR . $path;
156 14
        $this->saveTextToFile($data, $absolutePath);
157
    }
158
159
    /**
160
     * @param string $path
161
     * @param int $expires
162
     * @param callable $function
163
     * @param int $transform
164
     * @return mixed|null
165
     * @throws GeneratorException
166
     * @throws ConfigException
167
     */
168 1
    public function readFromCache($path, $expires = 300, $function = null, $transform = Cache::TEXT)
169
    {
170 1
        $data = null;
171 1
        Inspector::stats('[Cache] Reading data from cache: ' . json_encode(['path' => $path]), Inspector::SCOPE_DEBUG);
172 1
        if (file_exists(CACHE_DIR . DIRECTORY_SEPARATOR . $path)) {
173 1
            if (is_callable($function) && $this->hasExpiredCache($path, $expires)) {
174 1
                $data = $function();
175 1
                $this->storeData($path, $data, $transform, false, $expires);
0 ignored issues
show
Unused Code introduced by
The call to PSFS\base\Cache::storeData() has too many arguments starting with $expires. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

175
                $this->/** @scrutinizer ignore-call */ 
176
                       storeData($path, $data, $transform, false, $expires);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
176
            } else {
177 1
                $data = $this->getDataFromFile($path, $transform);
178
            }
179
        }
180 1
        return $data;
181
    }
182
183
    /**
184
     * @return bool
185
     */
186 2
    private static function checkAdminSite()
187
    {
188 2
        return Security::getInstance()->canAccessRestrictedAdmin();
189
    }
190
191
    /**
192
     * @return integer|boolean
193
     */
194 2
    public static function needCache()
195
    {
196 2
        $needCache = false;
197 2
        Logger::log('Checking cache requirements');
198 2
        if (!self::checkAdminSite() && !Config::getParam('debug') && Config::getParam('cache.data.enable', false)) {
199 1
            $action = Security::getInstance()->getSessionKey(self::CACHE_SESSION_VAR);
200 1
            Logger::log('Gathering cache params from Session', LOG_DEBUG, $action);
201 1
            if (null !== $action && array_key_exists('cache', $action) && $action['cache'] > 0) {
202 1
                $needCache = $action['cache'];
203
            }
204
        }
205 2
        return $needCache;
206
    }
207
208
    /**
209
     * @return array
210
     */
211 2
    public function getRequestCacheHash()
212
    {
213 2
        $hashPath = null;
214 2
        $filename = null;
215 2
        $action = Security::getInstance()->getSessionKey(self::CACHE_SESSION_VAR);
216 2
        Inspector::stats('[Cache] Gathering cache hash for request', Inspector::SCOPE_DEBUG);
217 2
        if (null !== $action && $action['cache'] > 0) {
218 2
            $query = $action['params'];
219 2
            $query[Api::HEADER_API_LANG] = Request::header(Api::HEADER_API_LANG, 'es');
220 2
            $filename = FileHelper::generateHashFilename($action['http'], $action['slug'], $query);
221 2
            $hashPath = FileHelper::generateCachePath($action, $query);
222 2
            Inspector::stats('[Cache] Cache file calculated: ' . json_encode(['file' => $filename, 'hash' => $hashPath]), Inspector::SCOPE_DEBUG);
223 2
            Logger::log('Cache file calculated', LOG_DEBUG, ['file' => $filename, 'hash' => $hashPath]);
224
        }
225 2
        return [$hashPath, $filename];
226
    }
227
228 1
    public function flushCache() {
229 1
        if(Config::getParam('cache.data.enable', false)) {
230 1
            Inspector::stats('[Cache] Flushing cache', Inspector::SCOPE_DEBUG);
231 1
            $action = Security::getInstance()->getSessionKey(self::CACHE_SESSION_VAR);
232 1
            if(is_array($action)) {
233 1
                $hashPath = FileHelper::generateCachePath($action, $action['params']) . '..' . DIRECTORY_SEPARATOR . ' .. ' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR;
234 1
                if(!file_exists($hashPath)) {
235 1
                    $hashPath = CACHE_DIR . DIRECTORY_SEPARATOR . $hashPath;
236
                }
237 1
                FileHelper::deleteDir($hashPath);
238
            }
239
        }
240
    }
241
}
242