PageRenderTime 66ms CodeModel.GetById 31ms RepoModel.GetById 0ms app.codeStats 1ms

/paraglide.php

http://github.com/bgoldman/Paraglide
PHP | 803 lines | 594 code | 168 blank | 41 comment | 182 complexity | f91c7bd3261a0b0065c44bce947c5c9d MD5 | raw file
  1. <?php
  2. /*
  3. Paragon
  4. Copyright (c) 2013 Brandon Goldman
  5. Released under the MIT License.
  6. */
  7. require_once dirname(__FILE__) . '/controller.php';
  8. Paraglide::init();
  9. class Paraglide {
  10. private static $_done_loading = false;
  11. private static $_controller_instance = null;
  12. private static $_request_types = array(
  13. 'csv' => 'text/csv',
  14. 'html' => 'text/html',
  15. 'json' => 'text/javascript',
  16. 'png' => 'image/png',
  17. 'rss' => 'application/rss+xml',
  18. 'txt' => 'text/plain',
  19. 'xml' => 'text/xml',
  20. );
  21. public static $action = null;
  22. public static $cache = null;
  23. public static $config = array();
  24. public static $controller = null;
  25. public static $data = array();
  26. public static $database = null;
  27. public static $databases = array();
  28. public static $layout = null;
  29. public static $nested_dir = '';
  30. public static $params = array();
  31. public static $request_type = null;
  32. public static $wrapper = null;
  33. private static function _execute_hook($source = null, $hook) {
  34. if ($source == 'file') {
  35. if (file_exists(APP_PATH . 'lib/hooks.php')) {
  36. require_once APP_PATH . 'lib/hooks.php';
  37. }
  38. if (method_exists('Hooks', $hook)) {
  39. call_user_func(array('Hooks', $hook));
  40. }
  41. return;
  42. }
  43. if ($source == 'controller') {
  44. if (method_exists(self::$_controller_instance, '_' . $hook)) {
  45. call_user_func(array(self::$_controller_instance, '_' . $hook));
  46. }
  47. }
  48. }
  49. private static function _render() {
  50. $master_view = 'layout';
  51. $modal_view = self::$nested_dir . 'modal.layout';
  52. $nested_view = self::$nested_dir . 'layout';
  53. $controller_view = self::$nested_dir . self::$controller . '/layout';
  54. $controller_wrapper = self::$nested_dir . self::$controller . '/wrapper';
  55. $local_view = self::$nested_dir . self::$controller . '/' . self::$action . '.layout';
  56. $local_wrapper = self::$nested_dir . self::$controller . '/' . self::$action . '.wrapper';
  57. if (!empty(self::$wrapper) && file_exists(APP_PATH . 'views/' . self::$wrapper . '.tpl')) {
  58. $wrapper = self::$wrapper;
  59. } elseif (file_exists(APP_PATH . 'views/' . $local_wrapper . '.tpl')) {
  60. $wrapper = $local_wrapper;
  61. } else if (file_exists(APP_PATH . 'views/' . $controller_wrapper . '.tpl')) {
  62. $wrapper = $controller_wrapper;
  63. }
  64. if (!empty(self::$layout) && file_exists(APP_PATH . 'views/' . self::$layout . '.tpl')) {
  65. $view = self::$layout;
  66. } elseif (!empty($_GET['modal'])) {
  67. $view = $modal_view;
  68. } elseif (file_exists(APP_PATH . 'views/' . $local_view . '.tpl')) {
  69. $view = $local_view;
  70. } elseif (file_exists(APP_PATH . 'views/' . $controller_view . '.tpl')) {
  71. $view = $controller_view;
  72. } elseif (file_exists(APP_PATH . 'views/' . $nested_view . '.tpl')) {
  73. $view = $nested_view;
  74. } else {
  75. $view = $master_view;
  76. }
  77. if (!empty($wrapper)) {
  78. ob_start();
  79. self::render($wrapper);
  80. self::$data['PAGE_CONTENT'] = ob_get_clean();
  81. }
  82. self::render($view);
  83. self::$_done_loading = true;
  84. }
  85. private static function _set_cache() {
  86. if (empty(self::$config['cache'])) {
  87. return;
  88. }
  89. if (empty(self::$config['cache'][ENVIRONMENT])) {
  90. return;
  91. }
  92. $config = self::$config['cache'][ENVIRONMENT];
  93. $class = $config['class'];
  94. if (!empty($class) && !class_exists($class)) {
  95. $filename = APP_PATH . 'lib/classes/' . self::inflect_underscore($class) . '.php';
  96. if (!file_exists($filename)) {
  97. self::error('Cache class \'' . $class . '\' not found at <em>' . $filename . '</em> in <strong>cache.cfg</strong>');
  98. }
  99. require_once $filename;
  100. if (!class_exists($class)) {
  101. self::error('Cache class \'' . $class . '\' not found in <em>' . $filename . '</em> in <strong>cache.cfg</strong>');
  102. }
  103. }
  104. if (!empty($config['path'])) {
  105. self::$cache = new $class($config['path']);
  106. } else {
  107. self::$cache = new $class();
  108. }
  109. $servers = explode(',', $config['servers']);
  110. foreach ($servers as $key => $server) {
  111. $server_parts = explode(':', $server);
  112. $host = $server_parts[0];
  113. $port = !empty($server_parts[1]) ? $server_parts[1] : null;
  114. self::$cache->addServer($host, $port, false);
  115. }
  116. }
  117. private static function _set_config_and_environment() {
  118. // set the main config first, because the environment relies on options in this config
  119. self::$config = array();
  120. self::$config['app'] = self::parse_config('app');
  121. // set the environment
  122. self::_set_environment();
  123. // set the other configs later, because they rely on the environment
  124. self::$config['cache'] = self::parse_config('cache', true);
  125. self::$config['database'] = self::parse_config('database', true);
  126. self::$config['mail'] = self::parse_config('mail', true);
  127. // DEFAULT_CONTROLLER is the controller your application executes if the one being accessed doesn't exist or one isn't provided (it's usually main)
  128. define('DEFAULT_CONTROLLER', self::$config['app']['main']['default_controller']);
  129. // make sure the default controller exists
  130. if (!file_exists(APP_PATH . 'controllers/' . DEFAULT_CONTROLLER . '_controller.php')) {
  131. self::error('Missing required default controller file <strong>controllers/' . DEFAULT_CONTROLLER . '_controller.php</strong>');
  132. }
  133. }
  134. private static function _set_constants() {
  135. if (!empty($_SERVER['REDIRECT_URL'])) {
  136. $_SERVER['REQUEST_URI'] = $_SERVER['REDIRECT_URL'];
  137. if (strpos($_SERVER['REQUEST_URI'], '?') === false && !empty($_SERVER['QUERY_STRING'])) {
  138. $_SERVER['REQUEST_URI'] .= '?' . $_SERVER['QUERY_STRING'];
  139. }
  140. }
  141. if (empty($_SERVER['REQUEST_URI'])) {
  142. $_SERVER['REQUEST_URI'] = '/';
  143. }
  144. // APP_PATH is the full server path to the directory of this application, with leading and trailing slashes
  145. // example: for http://www.example.com/shop/index.php/categories/5?size=medium, APP_PATH is something like /home/example.com/
  146. define('APP_PATH', realpath(dirname(__FILE__) . '/../../') . '/');
  147. // SITE_PATH is the full server path to the directory of this application relative to the domain, with leading and trailing slashes
  148. // example: for http://www.example.com/shop/index.php/categories/5?size=medium, SITE_PATH is something like /home/example.com/public_html/shop/
  149. $site_path = realpath(dirname($_SERVER['SCRIPT_FILENAME'])) . '/';
  150. define('SITE_PATH', $site_path);
  151. // SITE_ROOT is the path of this application relative to the domain, with leading and trailing slashes
  152. // example: for http://www.example.com/shop/index.php/categories/5?size=medium, SITE_ROOT is /shop/
  153. $docroot = realpath($_SERVER['DOCUMENT_ROOT']);
  154. if (substr($docroot, -1) == '/') $docroot = substr($docroot, 0, -1);
  155. if ($docroot === false) $docroot = '';
  156. define('SITE_ROOT', substr(SITE_PATH, strlen($docroot)));
  157. // CURRENT_URL is the this request's URL relative to the domain, with a leading slash and with or without a trailing slash
  158. // example: for http://www.example.com/shop/categories/5?size=medium, CURRENT_URL is /shop/categories/5?size=medium
  159. define('CURRENT_URL', $_SERVER['REQUEST_URI']);
  160. // SITE_FILENAME is the path and real filename of this application relative to the domain, with leading and trailing slashes
  161. // example: for http://www.example.com/shop/index[.php]/categories/5?size=medium, SITE_FILENAME is /shop/index.php/
  162. define('SITE_FILENAME', substr($_SERVER['SCRIPT_FILENAME'], strlen($_SERVER['DOCUMENT_ROOT'])));
  163. // LOCATION is this request's URL relative to SITE_ROOT, excluding the query string, without leading or trailing slashes
  164. // example: for http://www.example.com/shop/categories/5?size=medium, LOCATION is categories/5
  165. $location = $_SERVER['REQUEST_URI'];
  166. if (strpos($location, '?') != false) $location = substr($location, 0, strpos($location, '?'));
  167. if (substr($location, 0, strlen(SITE_FILENAME)) == SITE_FILENAME) $location = substr($location, strlen(SITE_FILENAME));
  168. if ($location === false) $location = '';
  169. if (substr($location, 0, strlen(SITE_ROOT)) == SITE_ROOT) $location = substr($location, strlen(SITE_ROOT));
  170. if (substr($location, 0, 1) == '/') $location = substr($location, 1);
  171. if ($location === false) $location = '';
  172. define('LOCATION', $location);
  173. // SITE_URL is path and accessed filename of this application relative to the domain, with leading and trailing slashes
  174. // example: for http://www.example.com/shop/index[.php]/categories/5?size=medium, SITE_URL is /shop/index[.php]/
  175. $uri = $_SERVER['REQUEST_URI'];
  176. $pos = strpos($uri, '?');
  177. if ($pos != false) $uri = substr($uri, 0, $pos);
  178. if (LOCATION != '') $uri = substr($uri, 0, -strlen(LOCATION));
  179. define('SITE_URL', $uri);
  180. }
  181. private static function _set_database() {
  182. if (empty(self::$config['database'])) {
  183. return;
  184. }
  185. self::$databases = array();
  186. $configs = array();
  187. foreach (self::$config['database'] as $key => $config) {
  188. if (
  189. $key != ENVIRONMENT
  190. && substr($key, 0, strlen(ENVIRONMENT . '-')) != ENVIRONMENT . '-'
  191. ) {
  192. continue;
  193. }
  194. if ($key == ENVIRONMENT) {
  195. $key = ENVIRONMENT . '-_default_';
  196. }
  197. $k = $key;
  198. $key = substr($key, strlen(ENVIRONMENT . '-'));
  199. $last_char = substr($key, -1);
  200. $last_digit = (int) $last_char;
  201. $last_digit = (string) $last_digit;
  202. $last_two_chars = substr($key, -2);
  203. $last_two_digits = (int) $last_two_chars;
  204. $last_two_digits = (string) $last_two_digits;
  205. if ($last_two_digits === $last_two_chars) {
  206. $key = substr($key, 0, -2);
  207. }
  208. if ($last_digit === $last_char) {
  209. $key = substr($key, 0, -1);
  210. }
  211. if (empty($configs[$key])) $configs[$key] = array();
  212. $configs[$key][] = $config;
  213. }
  214. foreach ($configs as $key => $key_configs) {
  215. shuffle($key_configs);
  216. $configs[$key] = $key_configs;
  217. }
  218. foreach ($configs as $key => $key_configs) {
  219. foreach ($key_configs as $config) {
  220. $class = $config['class'];
  221. if (!empty($class) && !class_exists($class)) {
  222. $filename = APP_PATH . 'lib/classes/' . self::inflect_underscore($class) . '.php';
  223. if (!file_exists($filename)) {
  224. self::error('Database class \'' . $class . '\' not found at <em>' . $filename . '</em> in <strong>database.cfg</strong>');
  225. }
  226. require_once $filename;
  227. if (!class_exists($class)) {
  228. self::error('Database class \'' . $class . '\' not found in <em>' . $filename . '</em> in <strong>database.cfg</strong>');
  229. }
  230. }
  231. $port = !empty($config['port']) ? $config['port'] : null;
  232. $socket = !empty($config['socket']) ? $config['socket'] : null;
  233. $database = @new $class($config['server'], $config['username'], $config['password'], null, $port, $socket);
  234. if (!$database) {
  235. continue;
  236. }
  237. if (!$database->select_db($config['name'])) {
  238. continue;
  239. }
  240. self::$databases[$key] = $database;
  241. break;
  242. }
  243. }
  244. if (empty(self::$databases)) {
  245. self::error('Database config not found for environment \'' . ENVIRONMENT . '\' in <strong>database.cfg</strong>');
  246. }
  247. self::$database = reset(self::$databases);
  248. }
  249. private static function _set_environment() {
  250. if (empty($_SERVER['REQUEST_URI'])) $_SERVER['REQUEST_URI'] = '';
  251. if (empty($_SERVER['HTTP_HOST'])) $_SERVER['HTTP_HOST'] = 'localhost';
  252. $server = strtolower($_SERVER['HTTP_HOST']);
  253. $environment_conf = !empty(self::$config['app']['environments']) ? self::$config['app']['environments'] : array();
  254. $deployment_conf = !empty(self::$config['app']['deployments']) ? self::$config['app']['deployments'] : array('main' => $server);
  255. $confs = array(
  256. 'ENVIRONMENT' => $environment_conf,
  257. 'DEPLOYMENT' => $deployment_conf,
  258. );
  259. foreach ($confs as $const => $conf) {
  260. $env_override = getenv('PARAGLIDE_' . $const);
  261. if ($env_override) {
  262. define($const, $env_override);
  263. continue;
  264. }
  265. foreach ($conf as $env => $domains) {
  266. $domains_array = explode(',', $domains);
  267. foreach ($domains_array as $domain) {
  268. $domain = trim($domain);
  269. $domain = strtolower($domain);
  270. $domain = str_replace('.', '\.', $domain);
  271. $domain = str_replace('*', '.+', $domain);
  272. if (!preg_match('/' . $domain . '/', $server)) {
  273. continue;
  274. }
  275. define($const, $env);
  276. break;
  277. }
  278. if (defined($const)) {
  279. break;
  280. }
  281. }
  282. if (!defined($const)) {
  283. $const_lower = strtolower($const);
  284. self::error('No ' . $const_lower . ' found for \'' . $server . '\' in <strong>config/app.cfg</strong>');
  285. }
  286. }
  287. error_reporting(ENVIRONMENT == 'live' ? 0 : E_ALL);
  288. }
  289. private static function _to_output_array($data) {
  290. if (empty($data)) {
  291. return null;
  292. }
  293. foreach ($data as $key => $value) {
  294. if (is_array($value)) {
  295. if (count($value) == 0) {
  296. continue;
  297. }
  298. $data[$key] = self::_to_output_array($value);
  299. } elseif (is_object($value) && method_exists($value, '__toArray')) {
  300. $data[$key] = $value->__toArray();
  301. $data[$key] = self::_to_output_array($data[$key]);
  302. } elseif (is_string($value)) {
  303. $data[$key] = utf8_encode($value);
  304. }
  305. }
  306. return $data;
  307. }
  308. public static function error($message) {
  309. if (!file_exists(APP_PATH . 'views/framework_error.tpl')) {
  310. die($message);
  311. }
  312. require_once APP_PATH . 'views/framework_error.tpl';
  313. die;
  314. }
  315. public static function inflect_camelize($word) {
  316. return str_replace(' ', '', ucwords(str_replace(array('_', ' '), ' ', $word)));
  317. }
  318. public static function inflect_underscore($word) {
  319. $return = '';
  320. for ($i = 0; $i < strlen($word); $i++) {
  321. $letter = $word{$i};
  322. if (strtolower($letter) !== $letter) {
  323. if ($i != 0) $return .= '_';
  324. $letter = strtolower($letter);
  325. }
  326. $return .= $letter;
  327. }
  328. return $return;
  329. }
  330. public static function init() {
  331. self::_set_constants();
  332. self::_set_config_and_environment();
  333. self::_set_database();
  334. self::_set_cache();
  335. self::_execute_hook('file', 'init');
  336. }
  337. public static function load($location, $skip_layout = false) {
  338. // fix the location
  339. if (strlen($location) > 0 && substr($location, 0, 1) == '/') $location = substr($location, 1);
  340. // set the query string if passed in
  341. $location_parts = explode('?', $location, 2);
  342. $location = $location_parts[0];
  343. // recalculate $_GET
  344. $query_string = $_SERVER['QUERY_STRING'];
  345. if (!empty($location_parts[1])) $query_string = $location_parts[1];
  346. $query_string_parts = explode('&', $query_string);
  347. $_GET = array();
  348. foreach ($query_string_parts as $part) {
  349. $pair = explode('=', $part);
  350. $key = urldecode($pair[0]);
  351. $value = isset($pair[1]) ? urldecode($pair[1]) : '';
  352. $_GET[$key] = $value;
  353. }
  354. if (empty(self::$request_type)) {
  355. // set the request type
  356. $pos = strrpos($location, '.');
  357. if ($pos != false) {
  358. $type = substr($location, $pos + 1);
  359. if (!empty(self::$_request_types[$type])) {
  360. self::$request_type = $type;
  361. $location = substr($location, 0, $pos);
  362. }
  363. }
  364. if (empty(self::$request_type)) {
  365. self::$request_type = 'html';
  366. }
  367. }
  368. // perform routing
  369. $params = explode('/', $location);
  370. $nested_dirs = array();
  371. foreach ($params as $argument) {
  372. if (strlen($argument) > 0) $nested_dirs[] = $argument;
  373. }
  374. $controller = DEFAULT_CONTROLLER;
  375. self::$nested_dir = '';
  376. while (true) {
  377. $try = APP_PATH . 'controllers/';
  378. $try_controller = str_replace('-', '_', DEFAULT_CONTROLLER);
  379. $i = count($nested_dirs);
  380. foreach ($nested_dirs as $dir) $try .= str_replace('-', '_', $dir) . '/';
  381. if (is_dir($try)) {
  382. $try_controller = str_replace('-', '_', isset($params[$i]) ? $params[$i] : DEFAULT_CONTROLLER);
  383. if (!file_exists($try . $try_controller . '_controller.php')) {
  384. $try_controller = str_replace('-', '_', DEFAULT_CONTROLLER);
  385. } else {
  386. $i++;
  387. }
  388. }
  389. if (!file_exists($try . $try_controller . '_controller.php')) {
  390. if (count($nested_dirs) == 0) {
  391. break;
  392. }
  393. $nested_dirs = array_slice($nested_dirs, 0, -1);
  394. continue;
  395. }
  396. if (count($nested_dirs) > 0) self::$nested_dir = implode('/', $nested_dirs) . '/';
  397. $params = array_slice($params, $i);
  398. $controller = $try_controller;
  399. break;
  400. }
  401. // set the controller
  402. self::$controller = $controller;
  403. // run file preprocessing
  404. self::_execute_hook('file', 'preprocess');
  405. // init the controller
  406. $controller_file = APP_PATH . 'controllers/';
  407. if (!empty(self::$nested_dir)) $controller_file .= self::$nested_dir . '/';
  408. $controller_file .= self::$controller . '_controller.php';
  409. require_once $controller_file;
  410. $controller_class = str_replace(' ', '', self::inflect_camelize(self::$controller)) . 'Controller';
  411. if (!class_exists($controller_class)) {
  412. self::error('Undefined controller class \'' . $controller_class . '\' in <strong>' . $controller_file . '</strong>');
  413. }
  414. self::$_controller_instance = new $controller_class();
  415. // load the classes, helpers, and models
  416. if (!empty(self::$_controller_instance->classes)) self::load_classes(self::$_controller_instance->classes);
  417. if (!empty(self::$_controller_instance->helpers)) self::load_helpers(self::$_controller_instance->helpers);
  418. if (!empty(self::$_controller_instance->models)) self::load_models(self::$_controller_instance->models);
  419. // set the function
  420. $action = !empty($params[0]) ? $params[0] : 'index';
  421. if (substr($action, 0, 1) == '_') $action = 'index';
  422. $function = str_replace('-', '_', $action);
  423. $function = method_exists(self::$_controller_instance, $function) ? $function : 'index';
  424. if (!empty($params[0]) && str_replace('-', '_', $params[0]) == $function) {
  425. $params = array_slice($params, 1);
  426. }
  427. foreach ($params as $key => $val) {
  428. $params[$key] = urldecode($val);
  429. }
  430. self::$params = $params;
  431. self::$action = str_replace('_', '-', $function);
  432. if (!method_exists(self::$_controller_instance, 'index')) {
  433. self::error('Missing required function \'index\' in <strong>' . $controller_file . '</strong>');
  434. }
  435. // run controller preprocessing
  436. self::_execute_hook('controller', 'preprocess');
  437. // start buffering the output for display later
  438. ob_start();
  439. // run the controller and generate the view
  440. call_user_func_array(array(self::$_controller_instance, $function), self::$params);
  441. // get the content
  442. self::$data['PAGE_CONTENT'] = ob_get_clean();
  443. // run any postprocessing
  444. self::_execute_hook('controller', 'postprocess');
  445. self::_execute_hook('file', 'postprocess');
  446. // if the request was redirected or if we want to skip the layout, stop here
  447. if (self::$_done_loading || $skip_layout) {
  448. echo self::$data['PAGE_CONTENT'];
  449. return;
  450. }
  451. // render
  452. self::_render();
  453. }
  454. public static function load_classes($classes) {
  455. if (empty($classes)) {
  456. return;
  457. }
  458. self::load_files('class', 'lib/classes', $classes);
  459. }
  460. public static function load_files($type, $dir, $files) {
  461. if (empty($files) || !is_array($files)) {
  462. return;
  463. }
  464. foreach ($files as $file) {
  465. $filename = self::inflect_underscore($file);
  466. $path = APP_PATH . $dir . "/{$filename}.php";
  467. if (!file_exists($path)) {
  468. $controller_file = 'controllers/' . self::$nested_dir . self::$controller . '_controller.php';
  469. self::error('Missing ' . $type . ' file \'' . $path . '\' referenced from <strong>' . $controller_file . '</strong>');
  470. }
  471. require_once $path;
  472. }
  473. }
  474. public static function load_helpers($helpers) {
  475. if (empty($helpers)) {
  476. return;
  477. }
  478. self::load_files('helper', 'lib/helpers', $helpers);
  479. }
  480. public static function load_models($models) {
  481. if (empty($models)) {
  482. return;
  483. }
  484. self::load_files('model', 'models', $models);
  485. }
  486. public static function long_url($controller = null, $action = null, $params = null, $query_string = null, $ssl = false) {
  487. $url = self::url($controller, $action, $params, $query_string, $ssl);
  488. if (substr($url, 0, 7) == 'http://') return $url;
  489. if (substr($url, 0, 8) == 'https://') return $url;
  490. $prefix = ($ssl == true) ? 'https' : 'http';
  491. return $prefix . '://' . $_SERVER['HTTP_HOST'] . $url;
  492. }
  493. public static function parse_config($file, $ignore_errors = false) {
  494. $local_filename = APP_PATH . 'config/local/' . $file . '.cfg';
  495. if (file_exists($local_filename)) $filename = $local_filename;
  496. if (defined('DEPLOYMENT') && empty($filename)) {
  497. $deployment_filename = APP_PATH . 'config/deployments/' . DEPLOYMENT . '/' . $file . '.cfg';
  498. if (file_exists($deployment_filename)) $filename = $deployment_filename;
  499. }
  500. if (empty($filename)) {
  501. $filename = APP_PATH . 'config/' . $file . '.cfg';
  502. if (!file_exists($filename)) {
  503. if ($ignore_errors) return null;
  504. die('Config file \'config/' . $file . '.cfg\' not found');
  505. }
  506. }
  507. return parse_ini_file($filename, true);
  508. }
  509. public static function query_string($params) {
  510. if (empty($params) || !is_array($params)) {
  511. return '';
  512. }
  513. $parts = array();
  514. foreach ($params as $key => $val) $parts[] = $key . '=' . $val;
  515. $string = '?' . implode('&', $parts);
  516. return $string;
  517. }
  518. public static function redirect($controller = null, $action = null, $params = null, $query_string = null, $ssl = false) {
  519. if (self::$request_type != 'html') {
  520. $url = $controller;
  521. if (strlen($action) > 0) {
  522. if (strlen($controller) > 0) $url .= '/';
  523. $url .= $action;
  524. }
  525. if (is_array($params)) $params = implode('/', $params);
  526. if ($params != '') $url .= '/' . $params;
  527. if (is_array($query_string)) $query_string = self::query_string($query_string);
  528. if ($query_string{0} != '?') $query_string = '?' . $query_string;
  529. if (strlen($query_string) == 1) $query_string = '';
  530. $url .= $query_string;
  531. if (!empty($_GET['jsonp'])) {
  532. $jsonp = $_GET['jsonp'];
  533. }
  534. $_GET = null;
  535. $_POST = null;
  536. if (!empty($jsonp)) {
  537. $_GET['jsonp'] = $jsonp;
  538. }
  539. self::load($url);
  540. die;
  541. }
  542. $url = self::url($controller, $action, $params, $query_string, $ssl);
  543. self::redirect_to($url);
  544. }
  545. public static function redirect_to($url) {
  546. header('Location: ' . $url);
  547. die;
  548. }
  549. public static function render($_view, $_data = null, $_buffer = false) {
  550. if (!$_buffer && self::$request_type == 'json') {
  551. $_data = self::_to_output_array($_data);
  552. $js = json_encode($_data);
  553. if (!empty($_GET['jsonp'])) $js = $_GET['jsonp'] . '(' . $js . ')';
  554. header('Content-Type: application/json');
  555. echo $js;
  556. self::$_done_loading = true;
  557. return;
  558. }
  559. if (!file_exists(APP_PATH . "views/{$_view}.tpl")) {
  560. self::error('View \'' . $_view . '\' not found at <strong>views/' . $_view . '.tpl</strong>');
  561. }
  562. if (!empty($_data) && is_array($_data)) {
  563. self::$data = array_merge(self::$data, $_data);
  564. }
  565. foreach (self::$data as $key => $val) {
  566. $$key = $val;
  567. }
  568. if ($_buffer) {
  569. ob_start();
  570. }
  571. require APP_PATH . 'views/' . $_view . '.tpl';
  572. if ($_buffer) {
  573. return ob_get_clean();
  574. }
  575. }
  576. public static function require_not_ssl() {
  577. if (empty($_SERVER['HTTPS'])) {
  578. return;
  579. }
  580. $host = $_SERVER['HTTP_HOST'];
  581. $url = $_SERVER['REQUEST_URI'];
  582. self::redirect_to('http://' . $host . $url);
  583. }
  584. public static function require_json() {
  585. if (self::$request_type == 'json') {
  586. return;
  587. }
  588. $url = SITE_ROOT . LOCATION . '.json';
  589. if (!empty($_GET)) $url .= self::query_string($_GET);
  590. self::redirect_to($url);
  591. }
  592. public static function require_ssl() {
  593. if (!empty($_SERVER['HTTPS'])) {
  594. return;
  595. }
  596. $host = $_SERVER['HTTP_HOST'];
  597. $url = $_SERVER['REQUEST_URI'];
  598. self::redirect_to('https://' . $host . $url);
  599. }
  600. public static function url($controller = null, $action = null, $params = null, $query_string = null, $ssl = false) {
  601. if ($_SERVER['SERVER_PORT'] == 443 && $ssl == false) {
  602. $prefix = 'http://' . $_SERVER['HTTP_HOST'];
  603. } elseif ($_SERVER['SERVER_PORT'] != 443 && $ssl == true) {
  604. $prefix = 'https://' . $_SERVER['HTTP_HOST'];
  605. } else {
  606. $prefix = '';
  607. }
  608. $prefix .= SITE_URL;
  609. if (substr($prefix, -1) != '/') $prefix .= '/';
  610. $url = $prefix . $controller;
  611. if (strlen($action) > 0) {
  612. if (strlen($controller) > 0) $url .= '/';
  613. $url .= $action;
  614. }
  615. if (!empty($params)) {
  616. $new_params = array();
  617. if (!is_array($params)) $params = array($params);
  618. foreach ($params as $key => $value) {
  619. if (strlen($value) > 0) {
  620. $new_params[] = $value;
  621. }
  622. }
  623. $params = $new_params;
  624. }
  625. if (is_array($params)) $params = implode('/', $params);
  626. if ($params != '') $url .= '/' . $params;
  627. if (!empty($query_string)) {
  628. if (is_array($query_string)) $query_string = self::query_string($query_string);
  629. if ($query_string{0} != '?') $query_string = '?' . $query_string;
  630. if (strlen($query_string) == 1) $query_string = '';
  631. $url .= $query_string;
  632. }
  633. return $url;
  634. }
  635. }