1: <?php
2: /**
3: * This file contains the the effective setting class.
4: *
5: * @package Core
6: * @subpackage Backend
7: * @author Frederic Schneider
8: * @copyright four for business AG <www.4fb.de>
9: * @license http://www.contenido.org/license/LIZENZ.txt
10: * @link http://www.4fb.de
11: * @link http://www.contenido.org
12: */
13:
14: defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.');
15:
16: /**
17: * Effective setting manager class.
18: * Provides a interface to retrieve effective
19: * settings.
20: *
21: * Requested effective settings will be cached at first time. Further requests
22: * will
23: * return cached settings.
24: *
25: * The order to retrieve a effective setting is:
26: * System => Client => Client (language) => Group => User
27: *
28: * - System properties can be overridden by the client
29: * - Client properties can be overridden by client language
30: * - Client language properties can be overridden by group
31: * - Group properties can be overridden by user
32: *
33: * @package Core
34: * @subpackage Backend
35: */
36: class cEffectiveSetting {
37:
38: /**
39: *
40: * @var array
41: */
42: protected static $_settings = array();
43:
44: /**
45: *
46: * @var cApiUser
47: */
48: protected static $_user;
49:
50: /**
51: *
52: * @var cApiClient
53: */
54: protected static $_client;
55:
56: /**
57: *
58: * @var cApiClientLanguage
59: */
60: protected static $_clientLanguage;
61:
62: /**
63: *
64: * @var bool
65: */
66: protected static $_loaded = array();
67:
68: /**
69: *
70: * @var cApiLanguage
71: */
72: protected static $_language;
73:
74: /**
75: * Loads all client, clientlanguage an system properties into an static array.
76: * The order is: System => Client => Client (language)
77: *
78: * @throws cDbException
79: * @throws cException
80: */
81: private static function _loadSettings() {
82: if (!isset(self::$_loaded[self::_getKeyPrefix()])) {
83: global $contenido;
84:
85: $typeGroup = array();
86:
87: //get all client settings
88: $client = self::_getClientInstance();
89: $settings = $client->getProperties();
90:
91: if (is_array($settings)) {
92: foreach ($settings as $setting) {
93: $key = self::_makeKey($setting['type'], $setting['name']);
94: self::_set($key, $setting['value']);
95: if (!isset($typeGroup[$setting['type']])) {
96: $typeGroup[$setting['type']] = array();
97: }
98: $typeGroup[$setting['type']][$setting['name']] = $setting['value'];
99: }
100: }
101:
102: //get all clientlang setting
103: $clientlang = self::_getClientLanguageInstance();
104: $settings = $clientlang->getProperties();
105:
106: if (is_array($settings)) {
107: foreach ($settings as $setting) {
108: $key = self::_makeKey($setting['type'], $setting['name']);
109: self::_set($key, $setting['value']);
110: if (!isset($typeGroup[$setting['type']])) {
111: $typeGroup[$setting['type']] = array();
112: }
113: $typeGroup[$setting['type']][$setting['name']] = $setting['value'];
114: }
115: }
116:
117: //get user settings
118: if (self::_isAuthenticated() && isset($contenido)) {
119: $user = self::_getUserInstance();
120: $settings = $user->getUserProperties();
121:
122: if (is_array($settings)) {
123: foreach ($settings as $setting) {
124: $key = self::_makeKey($setting['type'], $setting['name']);
125: self::_set($key, $setting['value']);
126: if (!isset($typeGroup[$setting['type']])) {
127: $typeGroup[$setting['type']] = array();
128: }
129: $typeGroup[$setting['type']][$setting['name']] = $setting['value'];
130: }
131: }
132: }
133:
134: //write cache by type settings
135: foreach ($typeGroup as $key => $group) {
136: $key = self::_makeKey($key, ' ');
137: self::_set($key, $group);
138: }
139: }
140:
141: self::$_loaded[self::_getKeyPrefix()] = true;
142: }
143:
144: /**
145: * Returns effective setting for a property.
146: *
147: * The order is: System => Client => Client (language) => Group => User
148: *
149: * System properties can be overridden by the group, and group properties
150: * can be overridden by the user.
151: *
152: * NOTE: If you provide a default value (other than empty string), then it will be returned back
153: * in case of not existing or empty setting.
154: *
155: * @param string $type
156: * The type of the item
157: * @param string $name
158: * The name of the item
159: * @param string $default [optional]
160: * default value
161: *
162: * @return bool|string
163: * Setting value or false
164: *
165: * @throws cDbException
166: * @throws cException
167: */
168: public static function get($type, $name, $default = '') {
169: self::_loadSettings();
170:
171: $key = self::_makeKey($type, $name);
172:
173: $value = self::_get($key);
174: if (false !== $value) {
175: return $value;
176: }
177:
178: if (false === $value) {
179: $value = getSystemProperty($type, $name);
180: }
181:
182: if (false === $value || NULL === $value) {
183: $value = $default;
184: } else if ('' === $value && '' !== $default) {
185: // NOTE: A non empty default value overrides an empty value
186: $value = $default;
187: }
188:
189: return $value;
190: }
191:
192: /**
193: * Returns effective setting for a type of properties.
194: * Caches also the collected settings, but contrary to get() it returns
195: * never cached entries.
196: *
197: * The order is:
198: * System => Client => Client (language) => Group => User
199: *
200: * System properties can be overridden by the group, and group
201: * properties can be overridden by the user.
202: *
203: * @param string $type
204: * The type of the item
205: *
206: * @return array
207: * Assoziative array like $arr[name] = value
208: *
209: * @throws cDbException
210: * @throws cException
211: */
212: public static function getByType($type) {
213: self::_loadSettings();
214:
215: $settings = getSystemPropertiesByType($type);
216:
217: $key = self::_makeKey($type, ' ');
218: if (is_array(self::_get($key))) {
219: $settings = array_merge($settings, self::_get($key));
220: }
221:
222: if (isset($settings) && is_array($settings)) {
223: return $settings;
224: } else {
225: return array();
226: }
227: }
228:
229: /**
230: * Sets a effective setting.
231: *
232: * Note:
233: * The setting will be set only in cache, not in persistency layer.
234: *
235: * @param string $type
236: * The type of the item
237: * @param string $name
238: * The name of the item
239: * @param string $value
240: * The value of the setting
241: */
242: public static function set($type, $name, $value) {
243: $key = self::_makeKey($type, $name);
244: self::_set($key, $value);
245: }
246:
247: /**
248: * Deletes a effective setting.
249: *
250: * Note:
251: * The setting will be deleted only from cache, not from persistency layer.
252: *
253: * @param string $type
254: * The type of the item
255: * @param string $name
256: * The name of the item
257: */
258: public static function delete($type, $name) {
259: $keySuffix = '_' . $type . '_' . $name;
260: foreach (self::$_settings as $key => $value) {
261: if (cString::findFirstPos($key, $keySuffix) !== false) {
262: unset(self::$_settings[$key]);
263: }
264: }
265: }
266:
267: /**
268: * Resets all properties of the effective settings class.
269: * Usable to start getting settings from scratch.
270: */
271: public static function reset() {
272: self::$_settings = array();
273: unset(self::$_user, self::$_client, self::$_clientLanguage);
274: }
275:
276: /**
277: * Returns the user object instance.
278: *
279: * @return cApiUser
280: */
281: protected static function _getUserInstance() {
282: global $auth;
283:
284: if (!isset(self::$_user)) {
285: self::$_user = new cApiUser($auth->auth['uid']);
286: }
287: return self::$_user;
288: }
289:
290: /**
291: * Returns the client language object instance.
292: *
293: * @return cApiClientLanguage
294: */
295: protected static function _getClientLanguageInstance() {
296: global $client, $lang;
297:
298: if (!isset(self::$_clientLanguage)) {
299: self::$_clientLanguage = new cApiClientLanguage(false, $client, $lang);
300: }
301: return self::$_clientLanguage;
302: }
303:
304: /**
305: * Returns the language object instance.
306: *
307: * @return cApiLanguage
308: */
309: protected static function _getLanguageInstance() {
310: global $lang;
311:
312: if (!isset(self::$_language)) {
313: self::$_language = new cApiLanguage($lang);
314: }
315: return self::$_language;
316: }
317:
318: /**
319: * Returns the client language object instance.
320: *
321: * @return cApiClient
322: */
323: protected static function _getClientInstance() {
324: $client = cRegistry::getClientId();
325:
326: if (!isset(self::$_client)) {
327: self::$_client = new cApiClient($client);
328: }
329: return self::$_client;
330: }
331:
332: /**
333: * Setting getter.
334: *
335: * @param string $key
336: * The setting key
337: * @return string
338: * bool setting value or false
339: */
340: protected static function _get($key) {
341: return (isset(self::$_settings[$key])) ? self::$_settings[$key] : false;
342: }
343:
344: /**
345: * Setting setter.
346: *
347: * @param string $key
348: * The setting key
349: * @param string $value
350: * Value to store
351: */
352: protected static function _set($key, $value) {
353: self::$_settings[$key] = $value;
354: }
355:
356: /**
357: * Setting key getter.
358: *
359: * @param string $type
360: * The type of the item
361: * @param string $name
362: * Name of the item
363: * @return string
364: * The setting key
365: */
366: protected static function _makeKey($type, $name) {
367: $key = self::_getKeyPrefix() . '_' . $type . '_' . $name;
368:
369: return $key;
370: }
371:
372: /**
373: * Returns the prefix for the internal key.
374: *
375: * @return string
376: */
377: protected static function _getKeyPrefix() {
378: global $auth;
379:
380: $prefix = '';
381:
382: if ($auth instanceof cAuth) {
383: if (!self::_isAuthenticated()) {
384: $prefix = cAuth::AUTH_UID_NOBODY;
385: } else {
386: $prefix = $auth->auth['uid'];
387: }
388: }
389:
390: if (cString::getStringLength($prefix) == 0) {
391: $prefix = cAuth::AUTH_UID_NOBODY;
392: }
393:
394: return $prefix;
395: }
396:
397: /**
398: * Checks global authentication object and if current user is authenticated.
399: *
400: * @return bool
401: */
402: protected static function _isAuthenticated() {
403: global $auth;
404: return $auth instanceof cAuth && $auth->isAuthenticated() && !$auth->isLoginForm();
405: }
406: }