PageRenderTime 77ms CodeModel.GetById 30ms RepoModel.GetById 1ms app.codeStats 1ms

/paraglide.php

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