Пример #1
0
 /**
  * Application entry point.
  */
 public static function start()
 {
     // hide errors
     error_reporting(E_ALL);
     ini_set('display_errors', 0);
     // use UTC on server
     date_default_timezone_set('UTC');
     // error/exception Handlers
     set_error_handler([__CLASS__, 'error']);
     set_exception_handler([__CLASS__, 'exception']);
     register_shutdown_function([__CLASS__, 'shutdown']);
     // configuration
     define('BRAMBLE_URL', self::get_app_url());
     Stopwatch::start()->register();
     Log::time('~init');
     // handle request
     Request::execute();
 }
Пример #2
0
 /**
  * @param bool $rebuild
  * @return RouteMap
  */
 public static function instance($rebuild = false)
 {
     return Cache::load('routes', function () {
         $lookup = [];
         // todo: add support for optional centralized routes
         foreach (Directory::search(BRAMBLE_DIR . '/Controllers', Directory::R_PHP, [Directory::R_HIDDEN]) as $file) {
             $controller_name = sprintf('%s\\%s', BRAMBLE_NS, substr(substr($file, strlen(BRAMBLE_DIR) + 1), 0, -4));
             $reflection_class = new \ReflectionClass($controller_name);
             if (!$reflection_class->isAbstract()) {
                 $controller = new $controller_name(Request::get());
                 if (!$controller instanceof Controller) {
                     throw new \Exception('Only controllers are allowed in this directory');
                 }
                 foreach ($controller->routes() as $route) {
                     $route->defaults(['controller' => $controller_name]);
                     $route->compile($lookup);
                 }
             }
         }
         return new self($lookup);
     }, $rebuild);
 }
Пример #3
0
 public function compile(array &$lookup)
 {
     // escape necessary characters other than :()<>
     $regex = preg_replace('`' . self::REGEX_ESCAPE . '`', '\\\\$0', $this->m_uri);
     // mark parentheses as non-capturing and optional
     if (strpos($regex, '(') !== false) {
         $regex = str_replace('(', '(?:', $regex);
         $regex = str_replace(')', ')?', $regex);
     }
     // match keys and replace with appropriate regexes
     if (preg_match_all(sprintf('/<(?<name>%s)>/', self::REGEX_KEY_NAME), $regex, $matches, PREG_SET_ORDER)) {
         foreach ($matches as $set) {
             $name = $set['name'];
             $key_regex = self::R_ANYTHING;
             if (isset($this->m_regexes[$name])) {
                 $key_regex = $this->m_regexes[$name];
                 if ($key_regex === self::R_LITERAL) {
                     $key_regex = $name;
                 }
             }
             $regex = str_replace($set[0], "(?<{$name}>{$key_regex})", $regex);
         }
     }
     // start with the lookup root
     $current =& $lookup;
     // find the starting literal components
     $position = strspn($this->m_uri ^ $regex, "");
     $similar = substr($this->m_uri, 0, $position);
     if (substr($similar, -1) === '(') {
         $similar = substr($similar, 0, -1);
     }
     if ($similar) {
         // add parts to the common lookup
         $similar_parts = array_filter(explode('/', $similar));
         foreach ($similar_parts as $part) {
             if (!isset($current[$part])) {
                 $current[$part] = [];
             }
             $current =& $current[$part];
         }
     }
     // wrap with safe delimiter
     $delimiter = '`';
     if (strpos($regex, $delimiter)) {
         $delimiter = "";
     }
     $regex = sprintf('%s^%s$%s', $delimiter, $regex, $delimiter);
     // build method mask
     $methods = 0;
     if ($this->m_methods) {
         foreach ($this->m_methods as $method) {
             $methods |= Request::method_flag($method);
         }
     }
     $compiled = new CompiledRoute($regex, $this->m_params, $this->m_actions, $methods, $this->m_method);
     // add compiled route to lookup
     $current[] = $compiled;
     return $compiled;
 }