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