]> git.mxchange.org Git - friendica.git/blob - include/cache.php
Class file relocations
[friendica.git] / include / cache.php
1 <?php
2 /**
3  * @file include/cache.php
4  *
5  * @brief Class for storing data for a short time
6  */
7
8 use Friendica\Core\Config;
9 use Friendica\Core\PConfig;
10 use Friendica\Database\DBM;
11
12 class Cache {
13         /**
14          * @brief Check for memcache and open a connection if configured
15          *
16          * @return object|boolean The memcache object - or "false" if not successful
17          */
18         public static function memcache() {
19                 if (!function_exists('memcache_connect')) {
20                         return false;
21                 }
22
23                 if (!Config::get('system', 'memcache')) {
24                         return false;
25                 }
26
27                 $memcache_host = Config::get('system', 'memcache_host', '127.0.0.1');
28                 $memcache_port = Config::get('system', 'memcache_port', 11211);
29
30                 $memcache = new Memcache;
31
32                 if (!$memcache->connect($memcache_host, $memcache_port)) {
33                         return false;
34                 }
35
36                 return $memcache;
37         }
38
39         /**
40          * @brief Return the duration for a given cache level
41          *
42          * @param integer $level Cache level
43          *
44          * @return integer The cache duration in seconds
45          */
46         private static function duration($level) {
47                 switch($level) {
48                         case CACHE_MONTH;
49                                 $seconds = 2592000;
50                                 break;
51                         case CACHE_WEEK;
52                                 $seconds = 604800;
53                                 break;
54                         case CACHE_DAY;
55                                 $seconds = 86400;
56                                 break;
57                         case CACHE_HOUR;
58                                 $seconds = 3600;
59                                 break;
60                         case CACHE_HALF_HOUR;
61                                 $seconds = 1800;
62                                 break;
63                         case CACHE_QUARTER_HOUR;
64                                 $seconds = 900;
65                                 break;
66                         case CACHE_FIVE_MINUTES;
67                                 $seconds = 300;
68                                 break;
69                         case CACHE_MINUTE;
70                                 $seconds = 60;
71                                 break;
72                 }
73                 return $seconds;
74         }
75
76         /**
77          * @brief Fetch cached data according to the key
78          *
79          * @param string $key The key to the cached data
80          *
81          * @return mixed Cached $value or "null" if not found
82          */
83         public static function get($key) {
84
85                 $memcache = self::memcache();
86                 if (is_object($memcache)) {
87                         // We fetch with the hostname as key to avoid problems with other applications
88                         $cached = $memcache->get(get_app()->get_hostname().":".$key);
89                         $value = @unserialize($cached);
90
91                         // Only return a value if the serialized value is valid.
92                         // We also check if the db entry is a serialized
93                         // boolean 'false' value (which we want to return).
94                         if ($cached === serialize(false) || $value !== false) {
95                                 return $value;
96                         }
97
98                         return null;
99                 }
100
101                 // Frequently clear cache
102                 self::clear($duration);
103
104                 $r = q("SELECT `v` FROM `cache` WHERE `k`='%s' LIMIT 1",
105                         dbesc($key)
106                 );
107
108                 if (DBM::is_result($r)) {
109                         $cached = $r[0]['v'];
110                         $value = @unserialize($cached);
111
112                         // Only return a value if the serialized value is valid.
113                         // We also check if the db entry is a serialized
114                         // boolean 'false' value (which we want to return).
115                         if ($cached === serialize(false) || $value !== false) {
116                                 return $value;
117                         }
118                 }
119
120                 return null;
121         }
122
123         /**
124          * @brief Put data in the cache according to the key
125          *
126          * The input $value can have multiple formats.
127          *
128          * @param string $key The key to the cached data
129          * @param mixed $valie The value that is about to be stored
130          * @param integer $duration The cache lifespan
131          */
132         public static function set($key, $value, $duration = CACHE_MONTH) {
133
134                 // Do we have an installed memcache? Use it instead.
135                 $memcache = self::memcache();
136                 if (is_object($memcache)) {
137                         // We store with the hostname as key to avoid problems with other applications
138                         $memcache->set(get_app()->get_hostname().":".$key, serialize($value), MEMCACHE_COMPRESSED, self::duration($duration));
139                         return;
140                 }
141
142                 /// @todo store the cache data in the same way like the config data
143                 q("REPLACE INTO `cache` (`k`,`v`,`expire_mode`,`updated`) VALUES ('%s','%s',%d,'%s')",
144                                 dbesc($key),
145                                 dbesc(serialize($value)),
146                                 intval($duration),
147                                 dbesc(datetime_convert()));
148         }
149
150         /**
151          * @brief Remove outdated data from the cache
152          *
153          * @param integer $maxlevel The maximum cache level that is to be cleared
154          */
155         public static function clear($max_level = CACHE_MONTH) {
156
157                 // Clear long lasting cache entries only once a day
158                 if (Config::get("system", "cache_cleared_day") < time() - self::duration(CACHE_DAY)) {
159                         if ($max_level == CACHE_MONTH) {
160                                 q("DELETE FROM `cache` WHERE `updated` < '%s' AND `expire_mode` = %d",
161                                         dbesc(datetime_convert('UTC','UTC',"now - 30 days")), intval(CACHE_MONTH));
162                         }
163
164                         if ($max_level <= CACHE_WEEK) {
165                                 q("DELETE FROM `cache` WHERE `updated` < '%s' AND `expire_mode` = %d",
166                                         dbesc(datetime_convert('UTC','UTC',"now - 7 days")), intval(CACHE_WEEK));
167                         }
168
169                         if ($max_level <= CACHE_DAY) {
170                                 q("DELETE FROM `cache` WHERE `updated` < '%s' AND `expire_mode` = %d",
171                                 dbesc(datetime_convert('UTC','UTC',"now - 1 days")), intval(CACHE_DAY));
172                         }
173                         Config::set("system", "cache_cleared_day", time());
174                 }
175
176                 if (($max_level <= CACHE_HOUR) && (Config::get("system", "cache_cleared_hour")) < time() - self::duration(CACHE_HOUR)) {
177                         q("DELETE FROM `cache` WHERE `updated` < '%s' AND `expire_mode` = %d",
178                                 dbesc(datetime_convert('UTC','UTC',"now - 1 hours")), intval(CACHE_HOUR));
179
180                         Config::set("system", "cache_cleared_hour", time());
181                 }
182
183                 if (($max_level <= CACHE_HALF_HOUR) && (Config::get("system", "cache_cleared_half_hour")) < time() - self::duration(CACHE_HALF_HOUR)) {
184                         q("DELETE FROM `cache` WHERE `updated` < '%s' AND `expire_mode` = %d",
185                                 dbesc(datetime_convert('UTC','UTC',"now - 30 minutes")), intval(CACHE_HALF_HOUR));
186
187                         Config::set("system", "cache_cleared_half_hour", time());
188                 }
189
190                 if (($max_level <= CACHE_QUARTER_HOUR) && (Config::get("system", "cache_cleared_quarter_hour")) < time() - self::duration(CACHE_QUARTER_HOUR)) {
191                         q("DELETE FROM `cache` WHERE `updated` < '%s' AND `expire_mode` = %d",
192                                 dbesc(datetime_convert('UTC','UTC',"now - 15 minutes")), intval(CACHE_QUARTER_HOUR));
193
194                         Config::set("system", "cache_cleared_quarter_hour", time());
195                 }
196
197                 if (($max_level <= CACHE_FIVE_MINUTES) && (Config::get("system", "cache_cleared_five_minute")) < time() - self::duration(CACHE_FIVE_MINUTES)) {
198                         q("DELETE FROM `cache` WHERE `updated` < '%s' AND `expire_mode` = %d",
199                                 dbesc(datetime_convert('UTC','UTC',"now - 5 minutes")), intval(CACHE_FIVE_MINUTES));
200
201                         Config::set("system", "cache_cleared_five_minute", time());
202                 }
203
204                 if (($max_level <= CACHE_MINUTE) && (Config::get("system", "cache_cleared_minute")) < time() - self::duration(CACHE_MINUTE)) {
205                         q("DELETE FROM `cache` WHERE `updated` < '%s' AND `expire_mode` = %d",
206                                 dbesc(datetime_convert('UTC','UTC',"now - 1 minutes")), intval(CACHE_MINUTE));
207
208                         Config::set("system", "cache_cleared_minute", time());
209                 }
210         }
211 }