PageRenderTime 46ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/bonfire/modules/settings/libraries/Settings_lib.php

http://github.com/ci-bonfire/Bonfire
PHP | 440 lines | 233 code | 59 blank | 148 comment | 47 complexity | 100b9a7418476609abeb8f21512b9831 MD5 | raw file
Possible License(s): LGPL-2.1
  1. <?php defined('BASEPATH') || exit('No direct script access allowed');
  2. /**
  3. * Bonfire
  4. *
  5. * An open source project to allow developers to jumpstart their development of
  6. * CodeIgniter applications.
  7. *
  8. * @package Bonfire
  9. * @author Bonfire Dev Team
  10. * @copyright Copyright (c) 2011 - 2014, Bonfire Dev Team
  11. * @license http://opensource.org/licenses/MIT The MIT License
  12. * @link http://cibonfire.com
  13. * @since Version 1.0
  14. * @filesource
  15. */
  16. /**
  17. * Settings Library
  18. *
  19. * Provides methods to retrieve settings from the database and/or config files,
  20. * and update settings in the database.
  21. *
  22. * @todo sort out the handling of module-specific settings, especially in the cache.
  23. *
  24. * @todo If someone retrieves a config value with item(), then attempts to change
  25. * the value with set(), it will attempt to update the value in the database...
  26. *
  27. * @package Bonfire\Modules\Settings\Libraries\Settings_lib
  28. * @author Bonfire Dev Team
  29. * @link http://cibonfire.com/docs/developer/settings#settings_lib
  30. */
  31. class Settings_lib
  32. {
  33. /** @var object A pointer to the CodeIgniter instance. */
  34. protected static $ci;
  35. /** @var array Settings cache. */
  36. private static $cache = array();
  37. /** @var array Error messages. */
  38. protected static $errors = array();
  39. /** @var array Hold observers to handle settings drivers */
  40. private static $observers = array();
  41. private static $settingsModelLoaded = false;
  42. /**
  43. * This constructor facilitates loading through CI.
  44. *
  45. * @return void
  46. */
  47. public function __construct()
  48. {
  49. self::init();
  50. self::find_all();
  51. }
  52. /**
  53. * Initialize the library.
  54. *
  55. * @return void
  56. */
  57. public static function init()
  58. {
  59. if (! is_object(self::$ci)) {
  60. self::$ci =& get_instance();
  61. }
  62. if (! class_exists('settings_model') && isset(self::$ci->load)) {
  63. self::$ci->load->model('settings/settings_model');
  64. }
  65. if (! self::$settingsModelLoaded
  66. && class_exists('settings_model')
  67. && isset(self::$ci->db)
  68. && ! empty(self::$ci->db->database)
  69. && self::$ci->db->table_exists(self::$ci->settings_model->get_table())
  70. ) {
  71. self::$settingsModelLoaded = true;
  72. }
  73. }
  74. /**
  75. * Get the requested settings value.
  76. *
  77. * @param string $name The name of the setting record to retrieve.
  78. *
  79. * @return mixed
  80. */
  81. public function __get($name)
  82. {
  83. return self::get($name);
  84. }
  85. /**
  86. * Set the requested setting value.
  87. *
  88. * @param string $name The name of the setting.
  89. * @param string $value The value to save.
  90. *
  91. * @return bool
  92. */
  93. public function __set($name, $value)
  94. {
  95. return self::set($name, $value);
  96. }
  97. /**
  98. * Get an error message previously set by the library.
  99. *
  100. * @param integer|null $index The index of the error message to retrieve.
  101. *
  102. * @return string|boolean Returns the message at the given index. If no index
  103. * was provided or no error message was found with the given index, returns
  104. * the last error message. If no errors have been set, returns false.
  105. */
  106. public static function getError($index = null)
  107. {
  108. if (is_null($index)
  109. || ! isset(self::$errors[$index])
  110. ) {
  111. return end(self::$errors);
  112. }
  113. return self::$errors[$index];
  114. }
  115. /**
  116. * Get the error messages previously set by the library.
  117. *
  118. * @return array An array of error messages, or an empty array.
  119. */
  120. public static function getErrors()
  121. {
  122. return self::$errors;
  123. }
  124. /**
  125. * Retrieve a setting.
  126. *
  127. * @param string $name The name of the item to retrieve.
  128. *
  129. * @return bool
  130. */
  131. public static function item($name)
  132. {
  133. if (isset(self::$cache[$name])) {
  134. return self::$cache[$name];
  135. }
  136. self::init();
  137. $value = null;
  138. if (self::$settingsModelLoaded) {
  139. $setting = self::$ci->settings_model->find_by('name', $name);
  140. if ($setting) {
  141. $value = $setting->value;
  142. }
  143. }
  144. // Setting doesn't exist, maybe it's a config option.
  145. if (is_null($value)) {
  146. $value = config_item($name);
  147. }
  148. // Store it for later.
  149. self::$cache[$name] = $value;
  150. return $value;
  151. }
  152. /**
  153. * Set a setting in the database.
  154. *
  155. * @param string $name Name of the setting.
  156. * @param string $value Value of the setting.
  157. * @param string $module Name of the module.
  158. *
  159. * @return boolean
  160. */
  161. public static function set($name, $value, $module = 'core')
  162. {
  163. if (! self::$settingsModelLoaded) {
  164. self::init();
  165. if (! self::$settingsModelLoaded) {
  166. self::$errors[] = 'Settings Model could not be loaded';
  167. return false;
  168. }
  169. }
  170. // If the value is cached and found in the database, update the database.
  171. if (isset(self::$cache[$name])
  172. && self::$ci->settings_model->find_by('name', $name)
  173. ) {
  174. $setting = self::$ci->settings_model->update_where('name', $name, array('value' => $value));
  175. } else {
  176. // Otherwise, insert the data.
  177. $setting = self::$ci->settings_model->insert(
  178. array(
  179. 'name' => $name,
  180. 'value' => $value,
  181. 'module' => $module,
  182. )
  183. );
  184. }
  185. self::$cache[$name] = $value;
  186. return true;
  187. }
  188. /**
  189. * Delete a setting in the database.
  190. *
  191. * @param string $name Name of the setting.
  192. * @param string $module Name of the module.
  193. *
  194. * @return boolean True if the setting was deleted successfully, else false.
  195. */
  196. public static function delete($name, $module = 'core')
  197. {
  198. if (! self::$settingsModelLoaded) {
  199. self::init();
  200. if (! self::$settingsModelLoaded) {
  201. self::$errors[] = 'Settings Model could not be loaded.';
  202. return false;
  203. }
  204. }
  205. if (! isset(self::$cache[$name])) {
  206. self::$errors[] = 'Error deleting setting: setting not found in cache.';
  207. return false;
  208. }
  209. if (self::$ci->settings_model->delete_where(array('name' => $name, 'module' => $module))) {
  210. unset(self::$cache[$name]);
  211. return true;
  212. }
  213. self::$errors[] = empty(self::$ci->settings_model->error) ? 'Error deleting setting from the database.' : self::$ci->settings_model->error;
  214. return false;
  215. }
  216. /**
  217. * Get all of the settings.
  218. *
  219. * @return array|null
  220. */
  221. public static function find_all()
  222. {
  223. if (! self::$settingsModelLoaded) {
  224. self::init();
  225. if (! self::$settingsModelLoaded) {
  226. self::$errors[] = 'Settings Model could not be loaded.';
  227. return null;
  228. }
  229. }
  230. if (self::$cache) {
  231. return self::$cache;
  232. }
  233. $settings = self::$ci->settings_model->find_all();
  234. foreach ($settings as $setting) {
  235. self::$cache[$setting->name] = $setting->value;
  236. }
  237. return self::$cache;
  238. }
  239. /**
  240. * Get a setting for specific search criteria.
  241. *
  242. * @see find_all_by for multiple matches.
  243. *
  244. * @param string $field Setting column name.
  245. * @param string $value Value ot match.
  246. *
  247. * @return array|null
  248. */
  249. public static function find_by($field = null, $value = null)
  250. {
  251. if (! self::$settingsModelLoaded) {
  252. self::init();
  253. if (! self::$settingsModelLoaded) {
  254. self::$errors[] = 'Settings Model could not be loaded.';
  255. return null;
  256. }
  257. }
  258. $settings = self::$ci->settings_model->find_by($field, $value);
  259. foreach ($settings as $setting) {
  260. self::$cache[$setting['name']] = $setting['value'];
  261. }
  262. return $settings;
  263. }
  264. /**
  265. * Get all of the settings based on search criteria.
  266. *
  267. * @see find_by for a single setting match.
  268. *
  269. * @param string $field Setting column name.
  270. * @param string $value Value ot match.
  271. *
  272. * @return array|null
  273. */
  274. public static function find_all_by($field = null, $value = null)
  275. {
  276. if (! self::$settingsModelLoaded) {
  277. self::init();
  278. if (! self::$settingsModelLoaded) {
  279. self::$errors[] = 'Settings Model could not be loaded.';
  280. return null;
  281. }
  282. }
  283. $settings = self::$ci->settings_model->find_all_by($field, $value);
  284. if (! empty($settings) && is_array($settings)) {
  285. foreach ($settings as $key => $value) {
  286. self::$cache[$key] = $value;
  287. }
  288. }
  289. return $settings;
  290. }
  291. /**
  292. * Perform a batch update of settings in the database. Inserts any data not
  293. * already in the database.
  294. *
  295. * @param array $data The settings to update in the database.
  296. *
  297. * @return boolean True on success, false on failure.
  298. */
  299. public static function update_batch($data)
  300. {
  301. if (! self::$settingsModelLoaded) {
  302. self::init();
  303. if (! self::$settingsModelLoaded) {
  304. self::$errors[] = 'Settings Model could not be loaded';
  305. return false;
  306. }
  307. }
  308. $index = 'name';
  309. $internalCache = array();
  310. $settings = self::$ci->settings_model->find_all();
  311. foreach ($settings as $setting) {
  312. $internalCache[$setting->name] = $setting->value;
  313. }
  314. $updateData = array();
  315. $insertData = array();
  316. foreach ($data as $record) {
  317. if (isset($internalCache[$record[$index]])) {
  318. $updateData[] = $record;
  319. } else {
  320. if (! isset($record['module'])) {
  321. $record['module'] = 'core';
  322. }
  323. $insertData[] = $record;
  324. }
  325. self::$cache[$record[$index]] = $record['value'];
  326. }
  327. $result = false;
  328. if (! empty($updateData)) {
  329. $result = self::$ci->settings_model->update_batch($updateData, $index);
  330. if (! $result && self::$ci->settings_model->error) {
  331. self::$errors[] = self::$ci->settings_model->error;
  332. }
  333. }
  334. if (! empty($insertData)) {
  335. $result = self::$ci->settings_model->insert_batch($insertData);
  336. if (! $result && self::$ci->settings_model->error) {
  337. self::$errors[] = self::$ci->settings_model->error;
  338. }
  339. }
  340. return $result;
  341. }
  342. // -------------------------------------------------------------------------
  343. // Add/Remove Observers
  344. // -------------------------------------------------------------------------
  345. public function attach($observer)
  346. {
  347. self::$observers[] = $observer;
  348. }
  349. public function detach($observer)
  350. {
  351. $remainingObservers = array();
  352. foreach (self::$observers as $key => $val) {
  353. if ($val === $observer) {
  354. // Remove all values from the cache which are attached to this
  355. // observer.
  356. continue;
  357. }
  358. $remainingObservers[] = $val;
  359. }
  360. self::$observers = $remainingObservers;
  361. }
  362. }
  363. // -----------------------------------------------------------------------------
  364. // ! HELPER METHOD
  365. // -----------------------------------------------------------------------------
  366. if (! function_exists('settings_item')) {
  367. /**
  368. * Helper method to retrieve a setting.
  369. *
  370. * @param string $name The name of the item to retrieve
  371. *
  372. * @return boolean|string Returns result of setting or false if none.
  373. */
  374. function settings_item($name = null)
  375. {
  376. if ($name === null) {
  377. return false;
  378. }
  379. return Settings_lib::item($name);
  380. }
  381. }