/** * Dispatcher * * @return void */ public function dispatch() { $request = $this->__request; $route_id = null; // set action if (isset($request[0]) && empty($request[0])) { $route_id = ''; System::log()->debug('Route detected for index', 'Eco'); } else { $is_route_loader = false; // routing while (list($route, $v) = each($this->__route)) { $mapped = explode('/', $route); $count_mapped = count($mapped); $i = 0; $param_wc_id = null; foreach ($mapped as $k => $part) { $i++; if (!empty($part) && $part[0] === ':') { $regex = null; if (($p = strpos($part, '@')) !== false) { $regex = substr($part, $p + 1); $part = substr($part, 0, $p); } if (($p = strrpos($part, ':')) > 0) { $cb = substr($part, $p + 1, strlen($part)); $part = substr($part, 0, $p); $this->mapParamCallback(substr($part, 1), $cb); } if (isset($request[$k]) && strlen($request[$k]) > 0) { if ($regex && substr($part, -1) !== '+' && !preg_match('#^' . $regex . '$#', $request[$k])) { continue 2; // regex failed } if (substr($part, -1) === '+') { $param_wc_id = substr(rtrim($part, '+'), 1); foreach (array_slice($request, $k) as $p) { if ($regex && !preg_match('#^' . $regex . '$#', $p)) { continue 3; // regex failed on wildcard param } $this->__param[$param_wc_id][] = $this->__paramCallback($param_wc_id, urldecode($p)); } } else { $part_k = substr(rtrim($part, '?'), 1); $this->__param[$part_k] = $this->__paramCallback($part_k, urldecode($request[$k])); } } else { if (substr($part, -1) !== '?') { continue 2; // required param missing } } } else { if (!isset($request[$k]) || $part !== $request[$k]) { // check for class route loader if (!$is_route_loader && isset($request[$k]) && substr($part, -1) === '*' && substr($part, 0, -1) == $request[$k]) { $this->__classRouteLoader($v); // invoke class route loader $is_route_loader = true; reset($this->__route); } continue 2; } } if ($i === $count_mapped || $param_wc_id !== null) { // look forward check if request continues if ($param_wc_id === null && count($request) > $count_mapped) { continue 2; // count mismatch } // set route $route_id = $route; System::log()->debug('Mapped route detected \'' . $route_id . '\'', 'Eco'); break 2; } } } } $this->route = '/' . $route_id; // no route || CLI only route + not CLI run if ($route_id === null || isset($this->__route_cli[$route_id]) && !$this->isCli()) { $route_id = null; if ($this->__404_callback !== null) { System::hook(System::HOOK_MIDDLE); $handled = call_user_func($this->__404_callback, $this->request); System::log()->debug('404 callback called'); if ($handled) { System::stop(); } } System::log()->debug('Failed to find route for request \'' . $this->request . '\'', 'Eco'); } // call action if (($route_id === null ? System::ERROR_NOT_FOUND : $this->action($route_id)) !== true) { System::error('Not found: \'' . $this->request . '\'', System::ERROR_NOT_FOUND, 'Eco'); } System::stop(); }