PageRenderTime 40ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/includes/core.php

http://micromvc-php.googlecode.com/
PHP | 511 lines | 195 code | 132 blank | 184 comment | 68 complexity | a4a6e7ae5c7d2844cde828ddd2ec3c8d MD5 | raw file
  1. <?php
  2. /**
  3. * Core
  4. *
  5. * This is the base class for all controllers.
  6. *
  7. * @package MicroMVC
  8. * @author David Pennington
  9. * @copyright Copyright (c) 2008 CodeXplorer
  10. * @license http://www.gnu.org/licenses/gpl-3.0.html
  11. * @link http://codexplorer.com
  12. * @version 1.0.0 <9/23/2008>
  13. ********************************** 80 Columns *********************************
  14. */
  15. class core {
  16. //Data for final site Layout
  17. public $data = null;
  18. //Name of final site layout file
  19. public $layout = 'layout';
  20. //Site Config
  21. public $config = array();
  22. //keeps us out of trouble with hook loops
  23. public $hook_in_progress = false;
  24. //Database object
  25. public $db = null;
  26. /**
  27. * Load the config values for this system
  28. *
  29. * @param array $config
  30. */
  31. function __construct($config=null) {
  32. //Set the core site config
  33. $this->config['site'] = $config;
  34. //load other config files
  35. foreach(array('hooks') as $name) {
  36. //Load it
  37. $this->load_config($name);
  38. }
  39. }
  40. /**
  41. * Load a config file
  42. * @param array $config
  43. */
  44. function load_config($name=null) {
  45. //Path to the config file
  46. $path = SITE_DIR. SITE_NAME. '/'. $name. '.php';
  47. //Check to see if it exists
  48. if(file_exists($path)) {
  49. //include the config
  50. require($path);
  51. //Set the values in our object
  52. //Overwrite if we have too ;D
  53. $this->config[$name] = $$name;
  54. } else {
  55. trigger_error($name. ' config does not exist!');
  56. }
  57. }
  58. /**
  59. * Load and initialize the database connection
  60. * @param array $config
  61. */
  62. function load_database() {
  63. //Don't load the DB object twice!!!
  64. if(!empty($this->db)) { return; }
  65. //Load the database config
  66. $this->load_config('database');
  67. //If the db class isn't already loaded - load it
  68. if (!class_exists('cxpdo')) {
  69. require_once(SITE_DIR. 'database/cxpdo.php');
  70. }
  71. //Create a new instance of the database
  72. $this->db = db::instance($this->config['database']);
  73. }
  74. /**
  75. * Loads and instantiates models, libraries, and other classes
  76. *
  77. * @param string the name of the class
  78. * @param string name for the class
  79. * @param array params to pass to the model constructor
  80. * @param string folder name of the class
  81. * @return void
  82. */
  83. function load($class=null, $name=null, $params=null, $path='libraries') {
  84. //If a model is NOT given
  85. if (!$class) { return; }
  86. //If a name is not given
  87. if(!$name) { $name = $class; }
  88. //If a model matches a variable - or it was already loaded
  89. if (isset($this->$name)) {
  90. return true;
  91. }
  92. //If the model file doesn't exist
  93. if (!file_exists(SITE_DIR. $path. '/'. $class. '.php')){
  94. trigger_error('Unable to locate the class "<b>'. $class. '</b>".');
  95. return;
  96. }
  97. //If the class isn't already loaded - load it
  98. if (!class_exists($class)) {
  99. require_once(SITE_DIR. $path. '/'. $class. '.php');
  100. }
  101. //Ok - lets create the object!
  102. $this->$name = new $class(($params ? $params : ''));
  103. /*
  104. * Make everything available to the object that was just created
  105. * @author http://CodeIgniter.com
  106. */
  107. foreach (array_keys(get_object_vars($this)) as $key) {
  108. //If a propery by this name doesn't already exist
  109. //And it is not this classe
  110. if (!isset($this->$name->$key) AND $key != $name) {
  111. // In some cases using references can cause
  112. // problems so we'll conditionally use them
  113. // If the magic __get() or __set() methods are used
  114. // in a Model references can't be used.
  115. if ((!method_exists($this->$name, '__get') && !method_exists($this->$name, '__set'))) {
  116. // Needed to prevent reference errors with some configurations
  117. $this->$name->$key = '';
  118. $this->$name->$key =& $this->$key;
  119. } else {
  120. $this->$name->$key = $this->$key;
  121. }
  122. }
  123. }
  124. return true;
  125. }
  126. /**
  127. * This function is used to load views files.
  128. *
  129. * @access private
  130. * @param String file path/name
  131. * @param array values to pass to the view
  132. * @param boolean return the output or print it?
  133. * @return void
  134. */
  135. function view($__file=null, $__variables=null, $__return=true) {
  136. //If no file is given - just return false
  137. if(!$__file) { return; }
  138. if(is_array($__variables)) {
  139. //Make each value passed to this view available for use
  140. foreach($__variables as $key => $variable) {
  141. $$key = $variable;
  142. }
  143. }
  144. //Delete them now
  145. $__variables = null;
  146. if (!file_exists(THEME_DIR. $__file. '.php')) {
  147. trigger_error('Unable to load the requested file: <b>'. $__file. '.php</b>');
  148. return;
  149. }
  150. /*
  151. * Buffer the output so we can return it
  152. */
  153. if($__return) {
  154. ob_start();
  155. // include() vs include_once() allows for multiple views with the same name
  156. include(THEME_DIR. $__file. '.php');
  157. //Get the output
  158. $buffer = ob_get_contents();
  159. @ob_end_clean();
  160. //Return the view
  161. return $buffer;
  162. //Else we just want to output to the screen
  163. } else {
  164. include(THEME_DIR. $__file. '.php');
  165. }
  166. }
  167. /**
  168. * Show a 400-500 Header error within the site theme
  169. *
  170. * @access public
  171. * @param string
  172. * @return void
  173. */
  174. function request_error($type='404') {
  175. //Clean the type of error from XSS stuff
  176. $type = preg_replace('/[^a-z0-9]+/i', '', $type);
  177. if ($type == '400') {
  178. header("HTTP/1.0 400 Bad Request");
  179. } elseif ($type == '401') {
  180. header("HTTP/1.0 401 Unauthorized");
  181. } elseif ($type == '403') {
  182. header("HTTP/1.0 403 Forbidden");
  183. } elseif ($type == '500') {
  184. header("HTTP/1.0 500 Internal Server Error");
  185. } else {
  186. $type = '404';
  187. header("HTTP/1.0 404 Not Found");
  188. }
  189. $this->data['content'] = $this->view('errors/'. $type);
  190. }
  191. /**
  192. * On close, show the output inside our layout template
  193. *
  194. * @access public
  195. * @param string
  196. * @return void
  197. */
  198. function render() {
  199. //If the user has NOT overriden this value
  200. if($this->layout == 'layout') {
  201. //Check to see if it is an ajax request
  202. if(AJAX_REQUEST) {
  203. $this->layout = 'ajax';
  204. }
  205. }
  206. // Load the template
  207. $output = $this->view($this->layout, $this->data);
  208. // Cache the file
  209. create_cache(md5(PAGE_NAME. AJAX_REQUEST), $output);
  210. // Show the output
  211. print $output;
  212. }
  213. /*************************** HOOK MANAGEMENT ********************/
  214. /**
  215. * Call Hook
  216. *
  217. * Calls a particular hook(s). Also, alows data to be
  218. * filtered by a hook(s) and the result returned.
  219. *
  220. * @access public
  221. * @param string the hook name
  222. * @param mixed Data to be parsed
  223. * @return mixed
  224. */
  225. function call_hook($name='', $data=null) {
  226. //If no hook is given OR found with that name
  227. if (!$name || !isset($this->config['hooks'][$name])) {
  228. return FALSE;
  229. }
  230. //If there are several hooks to call
  231. if(isset($this->config['hooks'][$name][0]) && is_array($this->config['hooks'][$name])) {
  232. //If no data was provided to be processed
  233. if(!$data) {
  234. //Run each hook
  235. foreach ($this->config['hooks'][$name] as $val) {
  236. $this->run_hook($val);
  237. }
  238. //done
  239. return true;
  240. } else {
  241. //Run each hook and filter the data
  242. foreach ($this->config['hooks'][$name] as $val) {
  243. $data = $this->run_hook($val, $data);
  244. }
  245. //return the result
  246. return $data;
  247. }
  248. //Else there is only one hook to run
  249. } else {
  250. //If we are to process/filter data
  251. if($data) {
  252. return $this->run_hook($this->config['hooks'][$name], $data);
  253. }
  254. //Else just call the hook
  255. $this->run_hook($this->config['hooks'][$name]);
  256. return TRUE;
  257. }
  258. }
  259. /**
  260. * Remove Hook
  261. *
  262. * remove a particular function from the given hook
  263. *
  264. * @access private
  265. * @param string the hook name
  266. * @param string the function name
  267. * @return void
  268. */
  269. function remove($name='', $function='') {
  270. //If there are several hooks to clear
  271. if(isset($this->config['hooks'][$name][0]) && is_array($this->config['hooks'][$name])) {
  272. foreach($this->config['hooks'][$name] as $key => $hook) {
  273. if($hook['function'] == $function) {
  274. unset($this->config['hooks'][$name][$key]);
  275. return true;
  276. }
  277. }
  278. //Else it is only one hook
  279. } else {
  280. if($this->config['hooks'][$name]['function'] == $function) {
  281. unset($this->config['hooks'][$name]);
  282. return true;
  283. }
  284. }
  285. }
  286. /**
  287. * Run Hook
  288. *
  289. * Runs a particular hook
  290. *
  291. * @access public
  292. * @param array the hook details
  293. * @param array optional data to be filtered
  294. * @return bool
  295. */
  296. function run_hook($hook=null, $data=null) {
  297. //If it is NOT a hook config
  298. if (!is_array($hook)) {
  299. return $data;
  300. }
  301. // -----------------------------------
  302. // Safety - Prevents run-away loops
  303. // -----------------------------------
  304. // If the script being called happens to have the same
  305. // hook call within it a loop can happen
  306. if ($this->hook_in_progress == TRUE) {
  307. return $data;
  308. }
  309. // -----------------------------------
  310. // Check each value
  311. // -----------------------------------
  312. foreach(array('class', 'object', 'function', 'file', 'path') as $type) {
  313. if(!empty($hook[$type])) {
  314. $$type = $hook[$type];
  315. } else {
  316. $$type = null;
  317. }
  318. }
  319. // -----------------------------------
  320. // Error Checking
  321. // -----------------------------------
  322. //If we are missing a lot of stuff...
  323. if (!$class && !$function && !$object) {
  324. return $data;
  325. }
  326. //If a function is being called we HAVE TO HAVE a file name!
  327. if ((!$class && !$object) && (!$file && $function)) {
  328. return $data;
  329. }
  330. //Default to "functions/" or "libraries/" for classes
  331. if(!$path) {
  332. if($class || $object) {
  333. $path = 'libraries';
  334. } else {
  335. $path = 'functions';
  336. }
  337. }
  338. // -----------------------------------
  339. // Set the in_progress flag
  340. // -----------------------------------
  341. $this->hook_in_progress = TRUE;
  342. // -----------------------------------
  343. // Call the requested class and/or function
  344. // -----------------------------------
  345. //Check for the object first
  346. if($object && isset($this->$object) && method_exists($this->$object, $function)) {
  347. //Run the function
  348. $output = $this->$object->$function($data);
  349. //Else try to run the class
  350. } elseif ($class) {
  351. //If a object name is not set
  352. if(!$object) {
  353. $object = $class;
  354. }
  355. //If we are able to load the class
  356. $this->load($class, $object, $data, $path);
  357. //If it was loaded
  358. if(isset($this->$object) && method_exists($this->$object, $function)) {
  359. //Run the function
  360. $output = $this->$object->$function($data);
  361. //Else the class just wanted to be loaded - so return the data
  362. } else {
  363. $output = $data;
  364. }
  365. //Else just run the function
  366. } elseif($function) {
  367. //If the function does not alreay exist
  368. if (!function_exists($function)) {
  369. require_once($path. '/'. $file);
  370. }
  371. $output = $function($data);
  372. //If a class/object/function was not found
  373. } else {
  374. $output = $data;
  375. }
  376. $this->hook_in_progress = FALSE;
  377. return $output;
  378. }
  379. }