|
| 1 | +<?php |
| 2 | + |
| 3 | +class Toro |
| 4 | +{ |
| 5 | + public static function serve($routes) |
| 6 | + { |
| 7 | + ToroHook::fire('before_request', compact('routes')); |
| 8 | + |
| 9 | + $request_method = strtolower($_SERVER['REQUEST_METHOD']); |
| 10 | + $path_info = '/'; |
| 11 | + if (!empty($_SERVER['PATH_INFO'])) { |
| 12 | + $path_info = $_SERVER['PATH_INFO']; |
| 13 | + } |
| 14 | + else if (!empty($_SERVER['ORIG_PATH_INFO']) && $_SERVER['ORIG_PATH_INFO'] !== '/index.php') { |
| 15 | + $path_info = $_SERVER['ORIG_PATH_INFO']; |
| 16 | + } |
| 17 | + else { |
| 18 | + if (!empty($_SERVER['REQUEST_URI'])) { |
| 19 | + $path_info = (strpos($_SERVER['REQUEST_URI'], '?') > 0) ? strstr($_SERVER['REQUEST_URI'], '?', true) : $_SERVER['REQUEST_URI']; |
| 20 | + } |
| 21 | + } |
| 22 | + |
| 23 | + $discovered_handler = null; |
| 24 | + $regex_matches = array(); |
| 25 | + |
| 26 | + if (isset($routes[$path_info])) { |
| 27 | + $discovered_handler = $routes[$path_info]; |
| 28 | + } |
| 29 | + else if ($routes) { |
| 30 | + $tokens = array( |
| 31 | + ':string' => '([a-zA-Z]+)', |
| 32 | + ':number' => '([0-9]+)', |
| 33 | + ':alpha' => '([a-zA-Z0-9-_]+)' |
| 34 | + ); |
| 35 | + foreach ($routes as $pattern => $handler_name) { |
| 36 | + $pattern = strtr($pattern, $tokens); |
| 37 | + if (preg_match('#^/?' . $pattern . '/?$#', $path_info, $matches)) { |
| 38 | + $discovered_handler = $handler_name; |
| 39 | + $regex_matches = $matches; |
| 40 | + break; |
| 41 | + } |
| 42 | + } |
| 43 | + } |
| 44 | + |
| 45 | + $result = null; |
| 46 | + |
| 47 | + $handler_instance = null; |
| 48 | + if ($discovered_handler) { |
| 49 | + if (is_string($discovered_handler)) { |
| 50 | + $handler_instance = new $discovered_handler(); |
| 51 | + } |
| 52 | + elseif (is_callable($discovered_handler)) { |
| 53 | + $handler_instance = $discovered_handler(); |
| 54 | + } |
| 55 | + } |
| 56 | + |
| 57 | + if ($handler_instance) { |
| 58 | + unset($regex_matches[0]); |
| 59 | + |
| 60 | + if (self::is_xhr_request() && method_exists($handler_instance, $request_method . '_xhr')) { |
| 61 | + header('Content-type: application/json'); |
| 62 | + header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); |
| 63 | + header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); |
| 64 | + header('Cache-Control: no-store, no-cache, must-revalidate'); |
| 65 | + header('Cache-Control: post-check=0, pre-check=0', false); |
| 66 | + header('Pragma: no-cache'); |
| 67 | + $request_method .= '_xhr'; |
| 68 | + } |
| 69 | + |
| 70 | + if (method_exists($handler_instance, $request_method)) { |
| 71 | + ToroHook::fire('before_handler', compact('routes', 'discovered_handler', 'request_method', 'regex_matches')); |
| 72 | + $result = call_user_func_array(array($handler_instance, $request_method), $regex_matches); |
| 73 | + ToroHook::fire('after_handler', compact('routes', 'discovered_handler', 'request_method', 'regex_matches', 'result')); |
| 74 | + } |
| 75 | + else { |
| 76 | + ToroHook::fire('404', compact('routes', 'discovered_handler', 'request_method', 'regex_matches')); |
| 77 | + } |
| 78 | + } |
| 79 | + else { |
| 80 | + ToroHook::fire('404', compact('routes', 'discovered_handler', 'request_method', 'regex_matches')); |
| 81 | + } |
| 82 | + |
| 83 | + ToroHook::fire('after_request', compact('routes', 'discovered_handler', 'request_method', 'regex_matches', 'result')); |
| 84 | + } |
| 85 | + |
| 86 | + private static function is_xhr_request() |
| 87 | + { |
| 88 | + return isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest'; |
| 89 | + } |
| 90 | +} |
| 91 | + |
| 92 | +class ToroHook |
| 93 | +{ |
| 94 | + private static $instance; |
| 95 | + |
| 96 | + private $hooks = array(); |
| 97 | + |
| 98 | + private function __construct() {} |
| 99 | + private function __clone() {} |
| 100 | + |
| 101 | + public static function add($hook_name, $fn) |
| 102 | + { |
| 103 | + $instance = self::get_instance(); |
| 104 | + $instance->hooks[$hook_name][] = $fn; |
| 105 | + } |
| 106 | + |
| 107 | + public static function fire($hook_name, $params = null) |
| 108 | + { |
| 109 | + $instance = self::get_instance(); |
| 110 | + if (isset($instance->hooks[$hook_name])) { |
| 111 | + foreach ($instance->hooks[$hook_name] as $fn) { |
| 112 | + call_user_func_array($fn, array(&$params)); |
| 113 | + } |
| 114 | + } |
| 115 | + } |
| 116 | + |
| 117 | + public static function get_instance() |
| 118 | + { |
| 119 | + if (empty(self::$instance)) { |
| 120 | + self::$instance = new ToroHook(); |
| 121 | + } |
| 122 | + return self::$instance; |
| 123 | + } |
| 124 | +} |
0 commit comments