PageRenderTime 63ms CodeModel.GetById 30ms RepoModel.GetById 0ms app.codeStats 0ms

/upload/system/68kb/modules/addons/libraries/Events.php

https://github.com/68kb/68kb
PHP | 446 lines | 233 code | 57 blank | 156 comment | 33 complexity | eca1db1cbf4ef4e4f71f7ce2d4687c62 MD5 | raw file
Possible License(s): LGPL-2.1
  1. <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
  2. /**
  3. * 68kb
  4. *
  5. * An open source knowledge base script
  6. *
  7. * @package 68kb
  8. * @author Eric Barnes (http://ericlbarnes.com)
  9. * @copyright Copyright (c) 2010, 68kb
  10. * @license http://68kb.com/user_guide/license.html
  11. * @link http://68kb.com
  12. * @since Version 2.0
  13. */
  14. // ------------------------------------------------------------------------
  15. /**
  16. * Events
  17. *
  18. * @subpackage Libraries
  19. * @link http://68kb.com/user_guide/
  20. *
  21. */
  22. class Events
  23. {
  24. /**
  25. * Global CI Object
  26. */
  27. protected $_ci;
  28. /**
  29. * Array of hook _listeners
  30. */
  31. protected $_listeners = array();
  32. /**
  33. * Array of add ons
  34. */
  35. public $add_ons = array();
  36. /**
  37. * Returned value from extension.
  38. */
  39. protected $_call_it = array();
  40. // ------------------------------------------------------------------------
  41. /**
  42. * Construct
  43. *
  44. * Allow users to extend the system.
  45. * Idea from the now defunct Iono
  46. */
  47. public function __construct()
  48. {
  49. $this->_ci = CI_Base::get_instance();
  50. $this->_ci->benchmark->mark('add_ons_start');
  51. // Directory helper
  52. $this->_ci->load->helper('directory');
  53. // load any active modules first
  54. $this->_load_modules();
  55. // now auto load core helpers
  56. // by having this after the modules load it
  57. // allows people to extend helpers
  58. $this->_core_helpers();
  59. $this->_ci->benchmark->mark('add_ons_end');
  60. }
  61. // ------------------------------------------------------------------------
  62. /**
  63. * Load Modules
  64. *
  65. * Loads all active modules
  66. *
  67. */
  68. private function _load_modules()
  69. {
  70. // Confirm the modules table and add-ons are allowed.
  71. if ( ! $this->_ci->db->table_exists('modules') OR ! $this->_ci->config->item('allow_addons'))
  72. {
  73. return FALSE;
  74. }
  75. // See if we have the results cached.
  76. if ( ! $results = $this->_ci->cache->get('load_addons'))
  77. {
  78. $this->_ci->db->select('module_directory, module_name')
  79. ->from('modules')
  80. ->where('module_active', 'yes')
  81. ->order_by('module_order')
  82. ->order_by('module_display_name');
  83. $query = $this->_ci->db->get();
  84. $results = $query->result();
  85. $this->_ci->cache->write($results, 'load_addons', 60);
  86. }
  87. // And away we go...
  88. foreach ($results as $row)
  89. {
  90. $dir = $row->module_directory;
  91. $extension = strtolower(str_replace(array(EXT, '_extension'), '', $dir).'_extension');
  92. $config = strtolower(str_replace(array(EXT, '_config'), '', $dir).'_config');
  93. // Be sure config file exists else it can't be active.
  94. if (file_exists(EXTPATH . $row->module_directory .'/'. $config . '.xml'))
  95. {
  96. $this->add_ons[$row->module_name] = $row->module_directory;
  97. }
  98. if (file_exists(EXTPATH . $row->module_directory .'/'. $extension . EXT))
  99. {
  100. include_once(EXTPATH . $row->module_directory .'/'. $extension . EXT);
  101. $class = ucfirst($row->module_directory).'_extension';
  102. if (class_exists($class))
  103. {
  104. new $class($this);
  105. log_message('debug', 'Extension loaded: '.$extension);
  106. }
  107. }
  108. }
  109. }
  110. // --------------------------------------------------------------------
  111. /**
  112. * Load Core Helpers
  113. *
  114. * This function auto loads helpers.
  115. *
  116. * @access public
  117. * @param array
  118. * @return void
  119. */
  120. private function _core_helpers()
  121. {
  122. foreach (directory_map(APPPATH .'modules/', 2) AS $folder => $dir)
  123. {
  124. if ( ! is_array($dir))
  125. {
  126. continue;
  127. }
  128. if (in_array('helpers', $dir))
  129. {
  130. foreach (directory_map(APPPATH .'modules/'.$folder.'/helpers', 1) AS $file)
  131. {
  132. $helper_file = strtolower(str_replace(EXT, '', str_replace('_helper', '', $file)));
  133. if (file_exists(APPPATH.'modules/'.$folder.'/helpers/'.$helper_file.'_helper'.EXT))
  134. {
  135. $this->_ci->load->helper($folder.'/'.$helper_file);
  136. }
  137. }
  138. }
  139. }
  140. }
  141. // ------------------------------------------------------------------------
  142. /**
  143. * Register a listener for a given hook
  144. *
  145. * @param string $hook
  146. * @param object $class_reference
  147. * @param string $method
  148. */
  149. public function register($hook, $class_reference, $method)
  150. {
  151. // Specifies a key so we can't define the same handler more than once
  152. $key = get_class($class_reference).'->'.$method;
  153. $this->_listeners[$hook][$key] = array($class_reference, $method);
  154. }
  155. // ------------------------------------------------------------------------
  156. /**
  157. * Trigger an event
  158. *
  159. * @param string $hook
  160. * @param mixed $data
  161. */
  162. public function trigger($hook, $data = '', $type = 'string')
  163. {
  164. // Reset the call it array
  165. $this->_call_it = array();
  166. // Now call any hooks
  167. if (isset($this->_listeners[$hook]) && is_array($this->_listeners[$hook]) && count($this->_listeners[$hook]) > 0)
  168. {
  169. foreach ($this->_listeners[$hook] as $listener)
  170. {
  171. // Set up variables
  172. $class = $listener[0];
  173. $method = $listener[1];
  174. if (method_exists($class,$method))
  175. {
  176. $this->_call_it[] = $class->$method($data);
  177. }
  178. }
  179. }
  180. return $this->trigger_return($type);
  181. }
  182. // ------------------------------------------------------------------------
  183. /**
  184. * Get the raw array of listener return values
  185. *
  186. * @param string $type
  187. * @return array
  188. */
  189. public function trigger_return($type = 'string')
  190. {
  191. //return a concat string of all the _listeners returns
  192. if ($type == 'string')
  193. {
  194. $string = '';
  195. foreach ($this->_call_it as $value)
  196. {
  197. $string .= $value;
  198. }
  199. return $string;
  200. }
  201. //return an array of all the _listeners returns
  202. if ($type == 'array')
  203. {
  204. return $this->_call_it;
  205. }
  206. }
  207. // ------------------------------------------------------------------------
  208. /**
  209. * Find any active extensions for a given hook
  210. *
  211. * @param string
  212. * @return bool
  213. **/
  214. public function active_hook($hook)
  215. {
  216. if (isset($this->_listeners[$hook]) && is_array($this->_listeners[$hook]) && count($this->_listeners[$hook]) > 0)
  217. {
  218. return TRUE;
  219. }
  220. return FALSE;
  221. }
  222. // ------------------------------------------------------------------------
  223. /**
  224. * Active
  225. *
  226. * Check if an add-on is active.
  227. *
  228. * @param string
  229. * @return bool
  230. */
  231. public function active($add_on = '')
  232. {
  233. return (isset($this->add_ons[$add_on])) ? TRUE : FALSE;
  234. }
  235. // ------------------------------------------------------------------------
  236. /**
  237. * Process tags
  238. *
  239. * This is used to process tags from a string. (DB Results)
  240. *
  241. * @param string - The data
  242. * @return string - The processed data
  243. */
  244. public function process_tags($data = '')
  245. {
  246. $result = $this->_ci->simpletags->parse($data, array(), array($this->_ci->events, 'parser_callback'));
  247. return $result['content'];
  248. }
  249. // ------------------------------------------------------------------------
  250. /**
  251. * Callback from template parser
  252. *
  253. * @param array
  254. * @return mixed
  255. */
  256. public function parser_callback($data)
  257. {
  258. if ( ! isset($data['segments'][0]) OR ! isset($data['segments'][1]))
  259. {
  260. return FALSE;
  261. }
  262. // Setup our paths from the data array
  263. $class = $data['segments'][0];
  264. $method = $data['segments'][1];
  265. $addon = strtolower($class);
  266. $return_data = '';
  267. if ($class == 'site')
  268. {
  269. $addon_path = APPPATH.'/libraries/parsers/Site_parser.php';
  270. if ( ! file_exists($addon_path))
  271. {
  272. $return = FALSE;
  273. }
  274. $this->_ci->load->library('parsers/Site_parser', $data);
  275. $return_data = $this->_process('site_parser', $method, $data);
  276. }
  277. elseif (in_array($class, $this->add_ons)) // This loads a library from the addons directory.
  278. {
  279. $addon_path = EXTPATH.$class.'/libraries/'.$class.EXT;
  280. if ( ! file_exists($addon_path))
  281. {
  282. log_message('error', 'Unable to load: '.$class);
  283. $return = FALSE;
  284. }
  285. else
  286. {
  287. // Load that library
  288. $this->_ci->load->library($class.'/'.$class, $data);
  289. // How about a language file?
  290. $lang_path = EXTPATH.$class.'/language/'.$this->_ci->config->item('language').'/'.$addon.'_lang'.EXT;
  291. if (file_exists($lang_path))
  292. {
  293. $this->_ci->lang->load($addon.'/'.$addon);
  294. }
  295. // Now the fun stuff!
  296. $return_data = $this->_process($class, $method, $data);
  297. }
  298. }
  299. else
  300. {
  301. // Now we are going to check the core "modules" and see if this is what they want
  302. $addon_path = APPPATH.'modules/'.$class.'/libraries/'.ucfirst($class).'_parser'.EXT;
  303. if ( ! file_exists($addon_path))
  304. {
  305. $addon_path = APPPATH.'modules/kb/libraries/'.ucfirst($class).'_parser'.EXT;
  306. if ( ! file_exists($addon_path))
  307. {
  308. log_message('error', 'Unable to load: '.$class);
  309. $return = FALSE;
  310. }
  311. else
  312. {
  313. $this->_ci->load->library('kb/'.$class.'_parser', $data);
  314. $return_data = $this->_process($class.'_parser', $method, $data);
  315. }
  316. }
  317. else
  318. {
  319. $this->_ci->load->library($class.'/'.$class.'_parser', $data);
  320. $return_data = $this->_process($class.'_parser', $method, $data);
  321. }
  322. }
  323. if (is_array($return_data) && ! empty($return_data))
  324. {
  325. if ( ! $this->_is_multi($return_data))
  326. {
  327. $return_data = $this->_make_multi($return_data);
  328. }
  329. $content = $data['content'];
  330. $parsed_return = '';
  331. $simpletags = new Simpletags();
  332. foreach ($return_data as $result)
  333. {
  334. $parsed = $simpletags->parse($content, $result);
  335. $parsed_return .= $parsed['content'];
  336. }
  337. unset($simpletags);
  338. $return_data = $parsed_return;
  339. }
  340. return $return_data;
  341. }
  342. // --------------------------------------------------------------------
  343. /**
  344. * Process
  345. *
  346. * Just process the class
  347. *
  348. * @access private
  349. * @param object
  350. * @param string
  351. * @param array
  352. * @return mixed
  353. */
  354. private function _process($class, $method, $data)
  355. {
  356. if (method_exists($class, $method))
  357. {
  358. return $this->_ci->$class->$method($data);
  359. }
  360. return FALSE;
  361. }
  362. // ------------------------------------------------------------------------
  363. /**
  364. * Ensure we have a multi array
  365. */
  366. private function _is_multi($array)
  367. {
  368. return (count($array) != count($array, 1));
  369. }
  370. // --------------------------------------------------------------------
  371. /**
  372. * Forces a standard array in multidimensional.
  373. *
  374. * @param array
  375. * @param int Used for recursion
  376. * @return array The multi array
  377. */
  378. private function _make_multi($flat, $i=0)
  379. {
  380. $multi = array();
  381. foreach ($flat as $item => $value)
  382. {
  383. $return[$i][$item] = $value;
  384. }
  385. return $return;
  386. }
  387. }
  388. /* End of file Events.php */
  389. /* Location: ./upload/system/68kb/modules/addons/libraries/Events.php */