Cache::getDataFromFile()   A
last analyzed

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
ccs 7
cts 7
cp 1
crap 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace PSFS\base;
4
5
use PSFS\base\config\Config;
6
use PSFS\base\exception\ConfigException;
7
use PSFS\base\exception\GeneratorException;
8
use PSFS\base\types\Api;
9
use PSFS\base\types\helpers\FileHelper;
10
use PSFS\base\types\helpers\GeneratorHelper;
11
use PSFS\base\types\helpers\Inspector;
12
use PSFS\base\types\traits\SingletonTrait;
13
14
/**
15
 * Class Cache
16
 * @package PSFS\base
17
 * Gestión de los ficheros de cache
18
 */
19
class Cache
20
{
21
    /**
22
     * @var \Memcache
23
     */
24
    protected $memcache = null;
25
26
    const JSON = 1;
27
    const TEXT = 2;
28
    const GZIP = 3;
29
    const JSONGZ = 4;
30
    const MEMCACHE = 5;
31
32
    const CACHE_SESSION_VAR = '__CACHE__';
33
34
    use SingletonTrait;
35
36 3
    public function __construct()
37
    {
38 3
        $this->setLoaded(true);
39
    }
40
41
    /**
42
     * @return bool
43
     */
44 10
    public static function canUseMemcache()
45
    {
46 10
        return Config::getParam('psfs.memcache', false) && !Config::getParam('debug') && class_exists('Memcached');
47
    }
48
49
    /**
50
     * @param string $data
51
     * @param string $path
52
     * @throws GeneratorException
53
     * @throws ConfigException
54
     */
55 20
    private function saveTextToFile($data, $path)
56
    {
57 20
        GeneratorHelper::createDir(dirname($path));
58 20
        if (false === FileHelper::writeFile($path, $data)) {
59
            throw new ConfigException(t('No se tienen los permisos suficientes para escribir en el fichero ') . $path);
60
        }
61
    }
62
63
    /**
64
     * @param string $path
65
     * @param int $transform
66
     * @param boolean $absolute
67
     * @return mixed
68
     */
69 23
    public function getDataFromFile($path, $transform = Cache::TEXT, $absolute = false)
70
    {
71 23
        Inspector::stats('[Cache] Gathering data from cache', Inspector::SCOPE_DEBUG);
72 23
        $data = null;
73 23
        $absolutePath = $absolute ? $path : CACHE_DIR . DIRECTORY_SEPARATOR . $path;
74 23
        if (file_exists($absolutePath)) {
75 13
            $data = FileHelper::readFile($absolutePath);
76
        }
77 23
        return self::extractDataWithFormat($data, $transform);
78
    }
79
80
    /**
81
     * @param string $path
82
     * @param int $expires
83
     * @param boolean $absolute
84
     * @return bool
85
     */
86 2
    private function hasExpiredCache($path, $expires = 300, $absolute = false)
87
    {
88 2
        Inspector::stats('[Cache] Checking expiration', Inspector::SCOPE_DEBUG);
89 2
        $absolutePath = ($absolute) ? $path : CACHE_DIR . DIRECTORY_SEPARATOR . $path;
90 2
        $lasModificationDate = filemtime($absolutePath);
91 2
        return ($lasModificationDate + $expires <= time());
92
    }
93
94
    /**
95
     * @param mixed $data
96
     * @param int $transform
97
     * @return mixed
98
     */
99 23
    public static function extractDataWithFormat($data = null, $transform = Cache::TEXT)
100
    {
101 23
        Inspector::stats('[Cache] Extracting data from cache', Inspector::SCOPE_DEBUG);
102
        switch ($transform) {
103
            case self::JSON:
104 23
                $data = json_decode($data ?: '', true);
105 23
                break;
106
            case self::JSONGZ:
107 6
                $data = self::extractDataWithFormat($data, self::GZIP);
108 6
                $data = self::extractDataWithFormat($data, self::JSON);
109 6
                break;
110
            case self::GZIP:
111 6
                if (null !== $data && function_exists('gzuncompress')) {
112 3
                    $data = @gzuncompress($data ?: '');
113
                }
114 6
                break;
115
        }
116 23
        return $data;
117
    }
118
119
    /**
120
     * @param string $data
121
     * @param int $transform
122
     * @return string
123
     */
124 20
    public static function transformData($data, $transform = Cache::TEXT)
125
    {
126 20
        Logger::log('Transform data in cache', LOG_DEBUG);
127
        switch ($transform) {
128
            case self::JSON:
129 19
                $data = json_encode($data, JSON_PRETTY_PRINT);
130 19
                break;
131
            case self::JSONGZ:
132 3
                $data = self::transformData($data, self::JSON);
133 3
                $data = self::transformData($data, self::GZIP);
134 3
                break;
135
            case self::GZIP:
136 3
                if (function_exists('gzcompress')) {
137 3
                    $data = gzcompress($data ?: '');
138
                }
139 3
                break;
140
        }
141 20
        return $data;
142
    }
143
144
    /**
145
     * @param string $path
146
     * @param mixed $data
147
     * @param int $transform
148
     * @param bool $absolute
149
     * @throws GeneratorException
150
     * @throws ConfigException
151
     */
152 20
    public function storeData($path, $data, $transform = Cache::TEXT, $absolute = false)
153
    {
154 20
        Inspector::stats('[Cache] Store data in cache', Inspector::SCOPE_DEBUG);
155 20
        $data = self::transformData($data, $transform);
156 20
        $absolutePath = $absolute ? $path : CACHE_DIR . DIRECTORY_SEPARATOR . $path;
157 20
        $this->saveTextToFile($data, $absolutePath);
158
    }
159
160
    /**
161
     * @param string $path
162
     * @param int $expires
163
     * @param callable $function
164
     * @param int $transform
165
     * @param bool $ignoreExpiration
166
     * @return mixed|null
167
     * @throws GeneratorException
168
     * @throws ConfigException
169
     */
170 2
    public function readFromCache($path, $expires = 300, $function = null, $transform = Cache::TEXT, $ignoreExpiration = false)
171
    {
172 2
        $data = null;
173 2
        Inspector::stats('[Cache] Reading data from cache: ' . json_encode(['path' => $path]), Inspector::SCOPE_DEBUG);
174 2
        if (file_exists(CACHE_DIR . DIRECTORY_SEPARATOR . $path)) {
175 2
            if (is_callable($function) && $this->hasExpiredCache($path, $expires) && !$ignoreExpiration) {
176 1
                $data = $function();
177 1
                $this->storeData($path, $data, $transform);
178
            } else {
179 2
                $data = $this->getDataFromFile($path, $transform);
180
            }
181
        }
182 2
        return $data;
183
    }
184
185
    /**
186
     * @return bool
187
     */
188 2
    private static function checkAdminSite()
189
    {
190 2
        return Security::getInstance()->canAccessRestrictedAdmin();
191
    }
192
193
    /**
194
     * @return integer|boolean
195
     */
196 2
    public static function needCache()
197
    {
198 2
        $needCache = false;
199 2
        Logger::log('Checking cache requirements');
200 2
        if (!self::checkAdminSite() && !Config::getParam('debug') && Config::getParam('cache.data.enable', false)) {
201 1
            $action = Security::getInstance()->getSessionKey(self::CACHE_SESSION_VAR);
202 1
            Logger::log('Gathering cache params from Session', LOG_DEBUG, $action);
203 1
            if (null !== $action && array_key_exists('cache', $action) && $action['cache'] > 0) {
204 1
                $needCache = $action['cache'];
205
            }
206
        }
207 2
        return $needCache;
208
    }
209
210
    /**
211
     * @return array
212
     */
213 2
    public function getRequestCacheHash()
214
    {
215 2
        $hashPath = null;
216 2
        $filename = null;
217 2
        $action = Security::getInstance()->getSessionKey(self::CACHE_SESSION_VAR);
218 2
        Inspector::stats('[Cache] Gathering cache hash for request', Inspector::SCOPE_DEBUG);
219 2
        if (null !== $action && $action['cache'] > 0) {
220 2
            $query = $action['params'];
221 2
            $query[Api::HEADER_API_LANG] = Request::header(Api::HEADER_API_LANG, 'es');
222 2
            $filename = FileHelper::generateHashFilename($action['http'], $action['slug'], $query);
223 2
            $hashPath = FileHelper::generateCachePath($action, $query);
224 2
            Inspector::stats('[Cache] Cache file calculated: ' . json_encode(['file' => $filename, 'hash' => $hashPath]), Inspector::SCOPE_DEBUG);
225 2
            Logger::log('Cache file calculated', LOG_DEBUG, ['file' => $filename, 'hash' => $hashPath]);
226
        }
227 2
        return [$hashPath, $filename];
228
    }
229
230 1
    public function flushCache()
231
    {
232 1
        if (Config::getParam('cache.data.enable', false)) {
233 1
            Inspector::stats('[Cache] Flushing cache', Inspector::SCOPE_DEBUG);
234 1
            $action = Security::getInstance()->getSessionKey(self::CACHE_SESSION_VAR);
235 1
            if (is_array($action)) {
236 1
                $hashPath = FileHelper::generateCachePath($action, $action['params']) . '..' . DIRECTORY_SEPARATOR . ' .. ' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR;
237 1
                if (!file_exists($hashPath)) {
238 1
                    $hashPath = CACHE_DIR . DIRECTORY_SEPARATOR . $hashPath;
239
                }
240 1
                FileHelper::deleteDir($hashPath);
241
            }
242
        }
243
    }
244
}
245