PageRenderTime 49ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

/index.php

https://github.com/Fusion/lenses
PHP | 614 lines | 509 code | 68 blank | 37 comment | 45 complexity | 2fd78434884885ffc3b3d3d5e8aa3f37 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. <?php
  2. /**
  3. * @package Lenses
  4. * @copyright (c) Chris F. Ravenscroft
  5. * @license See 'license.txt'
  6. */
  7. global $_debug;
  8. function __autoload($class_name)
  9. {
  10. global $inflector, $context;
  11. // CamelCase => camel_case
  12. $file_name = $inflector->inflectee($class_name)->toFile()->value();
  13. ClassLoader::instance()->loadClass($file_name);
  14. }
  15. function import($path)
  16. {
  17. ClassLoader::instance()->import($path);
  18. }
  19. function redirect($url, $redirect_message)
  20. {
  21. global $page_parameters;
  22. $page_parameters['action'] = 'redirect';
  23. $page_parameters['redirect_url'] = Config::$path . $url . '?msg=' . urlencode($redirect_message);
  24. }
  25. function notifyView($msg)
  26. {
  27. $notify_msg = addslashes($msg);
  28. // Copied from util.js...
  29. print <<<EOB
  30. <script type="text/javascript">
  31. if(parent)
  32. var myDoc = parent.document;
  33. else
  34. var myDoc = document;
  35. var notifyfield = myDoc.getElementById('notifyfield');
  36. if(!notifyfield)
  37. {
  38. var div = myDoc.createElement('div');
  39. div.id = 'notifyfield';
  40. myDoc.body.appendChild(div);
  41. }
  42. if(parent)
  43. parent.document.getElementById('notifyfield').innerHTML = '{$notify_msg}';
  44. else
  45. document.getElementById('notifyfield').innerHTML = '{$notify_msg}';
  46. </script>
  47. EOB;
  48. }
  49. global $extraheaders;
  50. function addheader($header)
  51. {
  52. global $extraheaders;
  53. $extraheaders .= $header;
  54. }
  55. global $extrajs;
  56. function addjs($js)
  57. {
  58. global $extrajs;
  59. $extrajs .= $js;
  60. }
  61. function quick_log($txt)
  62. {
  63. $f = @fopen('/tmp/fw.log', 'a+');
  64. if(!$f) return;
  65. @fputs($f, $txt);
  66. @fclose($f);
  67. }
  68. function include_here($path, $file)
  69. {
  70. include(dirname($path).'/'.$file);
  71. }
  72. class GoodException extends Exception {};
  73. // ---------------------------
  74. // Loggers
  75. class FirePHPLogger
  76. {
  77. function __construct()
  78. {
  79. ob_start();
  80. include('libs/FirePHPCore/fb.php');
  81. }
  82. public function info($arg)
  83. {
  84. fb($arg, FirePHP::INFO);
  85. }
  86. public function write($arg)
  87. {
  88. fb($arg);
  89. }
  90. public function error($arg)
  91. {
  92. fb($arg, FirePHP::ERROR);
  93. }
  94. }
  95. class TmpLogger
  96. {
  97. private function _write($str)
  98. {
  99. $f = fopen('/tmp/fw.log', 'a+');
  100. fwrite($f, $str);
  101. fclose($f);
  102. }
  103. public function info($arg)
  104. {
  105. $this->_write("INFO: $arg\n");
  106. }
  107. public function write($arg)
  108. {
  109. $this->_write("$arg\n");
  110. }
  111. public function error($arg)
  112. {
  113. $this->_write("ERROR: $arg\n");
  114. }
  115. }
  116. class EchoLogger
  117. {
  118. public function info($arg)
  119. {
  120. echo "INFO: $arg\n";
  121. }
  122. public function write($arg)
  123. {
  124. echo "$arg\n";
  125. }
  126. public function error($arg)
  127. {
  128. echo "ERROR: $arg\n";
  129. }
  130. }
  131. class NullLogger
  132. {
  133. public function info($arg) {}
  134. public function write($arg) {}
  135. public function error($arg) {}
  136. }
  137. class Logger
  138. {
  139. static private $_logger;
  140. private function __construct() {}
  141. static function instance()
  142. {
  143. if(!self::$_logger)
  144. {
  145. switch(strtolower(Config::$logger))
  146. {
  147. case 'firephp':
  148. self::$_logger = new FirePHPLogger();
  149. break;
  150. case 'tmp':
  151. self::$_logger = new TmpLogger();
  152. break;
  153. case 'echo':
  154. self::$_logger = new EchoLogger();
  155. break;
  156. default: // default - use in production
  157. self::$_logger = new NullLogger();
  158. }
  159. }
  160. return self::$_logger;
  161. }
  162. public function info($arg)
  163. {
  164. self::$_logger->info($arg);
  165. }
  166. }
  167. // ---------------------------
  168. // Translation
  169. function T($token, $context='g')
  170. {
  171. global $_translations, $db;
  172. if(!isset($_translations))
  173. $_translations = array();
  174. if(!isset($_translations[$context]))
  175. {
  176. $qry = 'SELECT token, translation FROM dict';
  177. $_translations[$context] = array();
  178. $rs = &$db->execute($qry);
  179. while(!$rs->EOF)
  180. {
  181. $_translations[$context][$rs->fields['token']] = $rs->fields['translation'];
  182. $rs->moveNext();
  183. }
  184. }
  185. return (isset($_translations[$context][$token]) ? $_translations[$context][$token] : $token);
  186. }
  187. // ---------------------------
  188. class ClassLoader
  189. {
  190. private $_classpath, $_imports, $_wildcardFiles;
  191. static private $_classLoader;
  192. private function __construct()
  193. {
  194. $this->_classpath = array(
  195. 'models',
  196. 'helpers',
  197. );
  198. $this->_imports = array();
  199. $this->_wildcardFiles = array();
  200. // Constants for classpath management
  201. define('SEARCH_CP', true);
  202. define('NO_SEARCH', false);
  203. // Constants for displayMessage()
  204. define('DISPLAY_BREAK', true);
  205. define('DISPLAY_NO_BREAK', false);
  206. // Session persistence constants
  207. define('SESSION_PERSIST', true);
  208. define('SESSION_NO_PERSIST',true);
  209. // Active records constants
  210. define('FIRST', 'f');
  211. define('ALL', 'a');
  212. }
  213. static function instance()
  214. {
  215. if(!self::$_classLoader)
  216. self::$_classLoader = new ClassLoader();
  217. return self::$_classLoader;
  218. }
  219. public function addToClasspath($path)
  220. {
  221. // Take precedence
  222. array_unshift($this->_classpath, $path);
  223. }
  224. public function import($path)
  225. {
  226. global $inflector;
  227. $c = $this->_getClass($path);
  228. if($c == '*')
  229. {
  230. $searchPath =
  231. $inflector->
  232. inflectee($this->_getPath($path))->
  233. toPath()->value();
  234. foreach($this->_classpath as $classpath)
  235. {
  236. $fullPath = $classpath . '/' . $searchPath;
  237. if(file_exists($fullPath) && is_dir($fullPath))
  238. {
  239. foreach(glob($fullPath . '/*.php') as $filename)
  240. {
  241. $filename = str_replace('.php', '', $filename);
  242. $p = strrpos($filename, '/');
  243. $c_name = substr($filename, $p+1);
  244. $this->_import($c_name, $filename, NO_SEARCH);
  245. }
  246. }
  247. }
  248. }
  249. else
  250. {
  251. $this->_import($c, $inflector->inflectee($path)->toPath()->value(), SEARCH_CP);
  252. }
  253. }
  254. function loadClass($fileName)
  255. {
  256. global $inflector, $context;
  257. if(isset($this->_imports[$fileName]))
  258. {
  259. include_once($this->_imports[$fileName] . '.php');
  260. return;
  261. }
  262. else
  263. {
  264. foreach($this->_classpath as $classpath)
  265. {
  266. $fullPath = $classpath . '/' . $fileName . '.php';
  267. if(file_exists($fullPath))
  268. {
  269. include_once($fullPath);
  270. return;
  271. }
  272. }
  273. throw new Exception("Class not found error: $fileName");
  274. }
  275. }
  276. private function _import($name, $path, $searchClasspath)
  277. {
  278. global $inflector;
  279. if(SEARCH_CP == $searchClasspath)
  280. {
  281. $found = false;
  282. foreach($this->_classpath as $classpath)
  283. {
  284. $fullPath = $classpath . '/' . $path . '.php';
  285. if(file_exists($fullPath))
  286. {
  287. $found = true;
  288. $path = str_replace('.php', '', $fullPath);
  289. break;
  290. }
  291. }
  292. if(!$found)
  293. throw new Exception("Class not found error: $path");
  294. }
  295. $key = $inflector->inflectee($name)->toFile()->value();
  296. $value = $inflector->inflectee($path)->toLower()->value();
  297. if(isset($this->_imports[$key]) && $this->_imports[$key] != $value)
  298. throw new Exception(
  299. "Package conflict when importing from $value.php: conflicts with " .
  300. $this->_imports[$key] . '.php');
  301. $this->_imports[$key] = $value;
  302. }
  303. private function _getClass($path)
  304. {
  305. if(false !== ($p = strrpos($path, '.')))
  306. return substr($path, $p+1);
  307. else
  308. return $path;
  309. # throw new Exception("Sorry, no class found in $path");
  310. }
  311. private function _getPath($path)
  312. {
  313. if(false !== ($p = strrpos($path, '.')))
  314. return substr($path, 0, $p);
  315. return '';
  316. }
  317. }
  318. // ---------------------------
  319. // It's always the same old story: controller does
  320. // its magic, asks model for time of the day,
  321. // then we render our view.
  322. // --------------------------- router
  323. class Router
  324. {
  325. static function run()
  326. {
  327. // Does whoever came up with magic_quotes_gpc deserve to die? Discuss!
  328. if(get_magic_quotes_gpc())
  329. {
  330. // Oh no!
  331. $inputs = array(&$_GET, &$_POST, &$_COOKIE);
  332. while(list($key, $value) = each($inputs))
  333. {
  334. foreach($value as $akey => $avalue)
  335. {
  336. if(is_array($avalue))
  337. $inputs[] = &$inputs[$key][$akey];
  338. else
  339. $inputs[$key][$akey] = stripslashes($avalue);
  340. }
  341. }
  342. unset($inputs);
  343. }
  344. //
  345. include('libs/error_reporter.php');
  346. register_shutdown_function('handleShutdown');
  347. set_error_handler("displayErrorScreen");
  348. set_exception_handler("displayExceptionScreen");
  349. include('config.php');
  350. Logger::instance()->info('Using FirePHP');
  351. include('libs/ajax.php');
  352. include('libs/inflector.php');
  353. include('libs/validator.php');
  354. include('libs/util.php');
  355. include('libs/form_tags.php');
  356. global $extraheaders, $extrajs;
  357. if(!empty(Config::$dblayer))
  358. {
  359. include('libs/adodb/adodb.inc.php');
  360. include('libs/adodb/adodb-active-record.inc.php');
  361. include('libs/adodb/adodb-exceptions.inc.php');
  362. include('libs/adodb/session/adodb-session2.php');
  363. global $db;
  364. $db = NewADOConnection(
  365. Config::$dbengine.'://'.
  366. Config::$dbuser.':'.
  367. Config::$dbpassword.'@'.
  368. Config::$dbhost.'/'.
  369. Config::$dbname);
  370. ADOdb_Active_Record::SetDatabaseAdapter($db);
  371. ADOdb_Session::config(
  372. Config::$dbengine,
  373. Config::$dbhost,
  374. Config::$dbuser,
  375. Config::$dbpassword,
  376. Config::$dbname,
  377. array('table' => 'sessions'));
  378. }
  379. else
  380. {
  381. // TODO Time to panic here!
  382. die("Please implement a better error handler.");
  383. }
  384. include('libs/base/base_object.php');
  385. include('libs/base/application_model.php');
  386. include('libs/base/application_controller.php');
  387. include('libs/base/active_record.php');
  388. include('libs/base/active_ws_record.php');
  389. // Member structure
  390. include('libs/models/member.php');
  391. include('libs/session.php');
  392. Session::start();
  393. new Ajax();
  394. // All done. Initialize configuration.
  395. Config::initialize();
  396. // Let's start routing. For real.
  397. global $context, $controller, $action;
  398. $controller = $action = null;
  399. // Are we using prettified URLs level 2?
  400. if(isset($_REQUEST['rewrite']) && $_REQUEST['rewrite']=='true')
  401. {
  402. $raw_url = preg_replace('#^' . Config::$path . '#', '', $_SERVER['REQUEST_URI']);
  403. // Restore good old GET variables
  404. if(false !== ($p = strpos($raw_url, '?')))
  405. {
  406. $gets = explode('&', substr($raw_url, $p + 1));
  407. foreach($gets as $get)
  408. {
  409. list($k, $v) = explode('=', $get);
  410. $_GET[$k] = $_REQUEST[$k] = urldecode($v);
  411. }
  412. }
  413. }
  414. else
  415. $raw_url = str_replace(Config::$path . 'index.php/', '', $_SERVER['REQUEST_URI']);
  416. $contextPrefix = '';
  417. $args = explode('/', $raw_url);
  418. if(count($args)>0)
  419. {
  420. if(!empty($args[0]))
  421. {
  422. if(isset(Config::$altroutes[$args[0]]))
  423. {
  424. $context = Config::$altroutes[$args[0]];
  425. }
  426. else
  427. {
  428. $context = $args[0];
  429. $contextPrefix = 'app/' . $context . '/';
  430. ClassLoader::instance()->addToClasspath('app/' . $context . '/models');
  431. ClassLoader::instance()->addToClasspath('app/' . $context . '/helpers');
  432. }
  433. }
  434. if(!empty($context))
  435. array_shift($args);
  436. if(count($args)>0)
  437. {
  438. $controller = $args[0];
  439. array_shift($args);
  440. if(count($args)>0)
  441. {
  442. $action = $args[0];
  443. array_shift($args);
  444. }
  445. else
  446. {
  447. $action = 'index';
  448. }
  449. }
  450. }
  451. if(empty($controller))
  452. {
  453. $controller = 'main';
  454. $action = 'index';
  455. }
  456. global $message_type, $message_css, $message_text, $page_parameters;
  457. $message_type = null;
  458. if(false !== ($p = strpos($action, '?')))
  459. {
  460. $action = substr($action, 0, $p);
  461. }
  462. // The code above is far from perfect...nothing beats a good old GET variable
  463. if(isset($_GET['msg']))
  464. {
  465. displayMessage(MESSAGE_INFO, $_GET['msg'], DISPLAY_NO_BREAK);
  466. }
  467. $controller_parts = explode('_', $controller);
  468. $controller_class = '';
  469. foreach($controller_parts as $part)
  470. {
  471. $controller_class .= ucwords($part);
  472. }
  473. $controller_class .= 'Controller';
  474. include($contextPrefix . 'controllers/' . $controller . '_controller.php');
  475. $c_class = new $controller_class($controller, $action, $args);
  476. if($action)
  477. {
  478. try
  479. {
  480. $c_class->$action();
  481. }
  482. catch(GoodException $ex)
  483. {
  484. // That's OK...just a quick way to exit an action callback
  485. // For instance, when invoking displayMessage()
  486. }
  487. // Give local scope to controller's vars
  488. $members = get_object_vars($c_class);
  489. foreach($members as $key => $value)
  490. {
  491. $$key = $value;
  492. }
  493. global $_debug;
  494. if(!empty($_debug))
  495. $debug = '<br />' . $_debug;
  496. else
  497. $debug = '';
  498. // Now, we have everything ready...let's grab a view, if any.
  499. if(empty($page_parameters['action']))
  500. {
  501. $v = $contextPrefix .
  502. 'views/' .
  503. (empty($options['controller']) ? $controller : $options['controller']) .
  504. '/' .
  505. (empty($options['view']) ? 'index' : $options['view']) .
  506. '.html.php';
  507. if(!(file_exists($v)))
  508. self::panic('Sorry, view [' . $v . '] does not exist.');
  509. if($options['header'])
  510. include("views/{$options['header']}.html.php");
  511. else
  512. include('views/header.html.php');
  513. if($options['body'])
  514. include("views/{$options['body']}.html.php");
  515. else
  516. include($v);
  517. if($options['footer'])
  518. include("views/{$options['footer']}.html.php");
  519. else
  520. include('views/footer.html.php');
  521. }
  522. else
  523. {
  524. switch($page_parameters['action'])
  525. {
  526. case 'redirect':
  527. include('views/redirect.html.php');
  528. break;
  529. case 'notify':
  530. notifyView($page_parameters['arg']->getMessage());
  531. break;
  532. case 'api':
  533. break;
  534. default:
  535. }
  536. }
  537. }
  538. }
  539. static function panic($ack)
  540. {
  541. die($ack);
  542. }
  543. }
  544. define(ROOT, dirname(__FILE__));
  545. Router::run();
  546. ?>