5 * Arbitrary configuration storage
7 * Please do not store booleans - convert to 0/1 integer values
8 * The get_?config() functions return boolean false for keys that are unset,
9 * and this could lead to subtle bugs.
11 * There are a few places in the code (such as the admin panel) where boolean
12 * configurations need to be fixed as of 10/08/2011.
16 // retrieve a "family" of config variables from database to cached storage
18 if(! function_exists('load_config')) {
19 function load_config($family) {
22 // To-Do: How to integrate APC here?
24 $r = q("SELECT * FROM `config` WHERE `cat` = '%s'", dbesc($family));
28 if ($family === 'config') {
29 $a->config[$k] = $rr['v'];
31 $a->config[$family][$k] = $rr['v'];
34 } else if ($family != 'config') {
36 $a->config[$family] = "!<unset>!";
40 // get a particular config variable given the family name
41 // and key. Returns false if not set.
42 // $instore is only used by the set_config function
43 // to determine if the key already exists in the DB
44 // If a key is found in the DB but doesn't exist in
45 // local config cache, pull it into the cache so we don't have
46 // to hit the DB again for this item.
48 if(! function_exists('get_config')) {
49 function get_config($family, $key, $instore = false) {
54 // Looking if the whole family isn't set
55 if(isset($a->config[$family])) {
56 if($a->config[$family] === '!<unset>!') {
61 if(isset($a->config[$family][$key])) {
62 if($a->config[$family][$key] === '!<unset>!') {
65 return $a->config[$family][$key];
69 // If APC is enabled then fetch the data from there, else try XCache
70 if (function_exists("apc_fetch") AND function_exists("apc_exists"))
71 if (apc_exists($family."|".$key)) {
72 $val = apc_fetch($family."|".$key);
73 $a->config[$family][$key] = $val;
75 if ($val === '!<unset>!')
80 elseif (function_exists("xcache_fetch") AND function_exists("xcache_isset"))
81 if (xcache_isset($family."|".$key)) {
82 $val = xcache_fetch($family."|".$key);
83 $a->config[$family][$key] = $val;
85 if ($val === '!<unset>!')
91 $ret = q("SELECT `v` FROM `config` WHERE `cat` = '%s' AND `k` = '%s' LIMIT 1",
97 $val = (preg_match("|^a:[0-9]+:{.*}$|s", $ret[0]['v'])?unserialize( $ret[0]['v']):$ret[0]['v']);
98 $a->config[$family][$key] = $val;
100 // If APC is enabled then store the data there, else try XCache
101 if (function_exists("apc_store"))
102 apc_store($family."|".$key, $val, 600);
103 elseif (function_exists("xcache_set"))
104 xcache_set($family."|".$key, $val, 600);
109 $a->config[$family][$key] = '!<unset>!';
111 // If APC is enabled then store the data there, else try XCache
112 if (function_exists("apc_store"))
113 apc_store($family."|".$key, '!<unset>!', 600);
114 elseif (function_exists("xcache_set"))
115 xcache_set($family."|".$key, '!<unset>!', 600);
120 // Store a config value ($value) in the category ($family)
121 // under the key ($key)
122 // Return the value, or false if the database update failed
124 if(! function_exists('set_config')) {
125 function set_config($family,$key,$value) {
128 // If $a->config[$family] has been previously set to '!<unset>!', then
129 // $a->config[$family][$key] will evaluate to $a->config[$family][0], and
130 // $a->config[$family][$key] = $value will be equivalent to
131 // $a->config[$family][0] = $value[0] (this causes infuriating bugs),
132 // so unset the family before assigning a value to a family's key
133 if($a->config[$family] === '!<unset>!')
134 unset($a->config[$family]);
136 // manage array value
137 $dbvalue = (is_array($value)?serialize($value):$value);
138 $dbvalue = (is_bool($dbvalue) ? intval($dbvalue) : $dbvalue);
139 if(get_config($family,$key,true) === false) {
140 $a->config[$family][$key] = $value;
141 $ret = q("INSERT INTO `config` ( `cat`, `k`, `v` ) VALUES ( '%s', '%s', '%s' ) ",
151 $ret = q("UPDATE `config` SET `v` = '%s' WHERE `cat` = '%s' AND `k` = '%s'",
157 $a->config[$family][$key] = $value;
159 // If APC is enabled then store the data there, else try XCache
160 if (function_exists("apc_store"))
161 apc_store($family."|".$key, $value, 600);
162 elseif (function_exists("xcache_set"))
163 xcache_set($family."|".$key, $value, 600);
171 if(! function_exists('load_pconfig')) {
172 function load_pconfig($uid,$family) {
174 $r = q("SELECT * FROM `pconfig` WHERE `cat` = '%s' AND `uid` = %d",
181 $a->config[$uid][$family][$k] = $rr['v'];
183 } else if ($family != 'config') {
185 $a->config[$uid][$family] = "!<unset>!";
191 if(! function_exists('get_pconfig')) {
192 function get_pconfig($uid,$family, $key, $instore = false) {
197 // Looking if the whole family isn't set
198 if(isset($a->config[$uid][$family])) {
199 if($a->config[$uid][$family] === '!<unset>!') {
204 if(isset($a->config[$uid][$family][$key])) {
205 if($a->config[$uid][$family][$key] === '!<unset>!') {
208 return $a->config[$uid][$family][$key];
212 // If APC is enabled then fetch the data from there, else try XCache
213 if (function_exists("apc_fetch") AND function_exists("apc_exists"))
214 if (apc_exists($uid."|".$family."|".$key)) {
215 $val = apc_fetch($uid."|".$family."|".$key);
216 $a->config[$uid][$family][$key] = $val;
218 if ($val === '!<unset>!')
223 elseif (function_exists("xcache_get") AND function_exists("xcache_isset"))
224 if (xcache_isset($uid."|".$family."|".$key)) {
225 $val = xcache_get($uid."|".$family."|".$key);
226 $a->config[$uid][$family][$key] = $val;
228 if ($val === '!<unset>!')
235 $ret = q("SELECT `v` FROM `pconfig` WHERE `uid` = %d AND `cat` = '%s' AND `k` = '%s' LIMIT 1",
242 $val = (preg_match("|^a:[0-9]+:{.*}$|s", $ret[0]['v'])?unserialize( $ret[0]['v']):$ret[0]['v']);
243 $a->config[$uid][$family][$key] = $val;
245 // If APC is enabled then store the data there, else try XCache
246 if (function_exists("apc_store"))
247 apc_store($uid."|".$family."|".$key, $val, 600);
248 elseif (function_exists("xcache_set"))
249 xcache_set($uid."|".$family."|".$key, $val, 600);
254 $a->config[$uid][$family][$key] = '!<unset>!';
256 // If APC is enabled then store the data there, else try XCache
257 if (function_exists("apc_store"))
258 apc_store($uid."|".$family."|".$key, '!<unset>!', 600);
259 elseif (function_exists("xcache_set"))
260 xcache_set($uid."|".$family."|".$key, '!<unset>!', 600);
265 if(! function_exists('del_config')) {
266 function del_config($family,$key) {
269 if(x($a->config[$family],$key))
270 unset($a->config[$family][$key]);
271 $ret = q("DELETE FROM `config` WHERE `cat` = '%s' AND `k` = '%s'",
275 // If APC is enabled then delete the data from there, else try XCache
276 if (function_exists("apc_delete"))
277 apc_delete($family."|".$key);
278 elseif (function_exists("xcache_unset"))
279 xcache_unset($family."|".$key);
286 // Same as above functions except these are for personal config storage and take an
287 // additional $uid argument.
289 if(! function_exists('set_pconfig')) {
290 function set_pconfig($uid,$family,$key,$value) {
294 // manage array value
295 $dbvalue = (is_array($value)?serialize($value):$value);
297 if(get_pconfig($uid,$family,$key,true) === false) {
298 $a->config[$uid][$family][$key] = $value;
299 $ret = q("INSERT INTO `pconfig` ( `uid`, `cat`, `k`, `v` ) VALUES ( %d, '%s', '%s', '%s' ) ",
309 $ret = q("UPDATE `pconfig` SET `v` = '%s' WHERE `uid` = %d AND `cat` = '%s' AND `k` = '%s'",
316 $a->config[$uid][$family][$key] = $value;
318 // If APC is enabled then store the data there, else try XCache
319 if (function_exists("apc_store"))
320 apc_store($uid."|".$family."|".$key, $value, 600);
321 elseif (function_exists("xcache_set"))
322 xcache_set($uid."|".$family."|".$key, $value, 600);
330 if(! function_exists('del_pconfig')) {
331 function del_pconfig($uid,$family,$key) {
334 if(x($a->config[$uid][$family],$key))
335 unset($a->config[$uid][$family][$key]);
336 $ret = q("DELETE FROM `pconfig` WHERE `uid` = %d AND `cat` = '%s' AND `k` = '%s'",