/** * Calls the closure or class/method pair assigned to route * * @param mixed $params Parameters to pass to the class construction or closure * If a route calls a closure, $params is prepended to the * URL pattern values array. If the route calls a class * and method, $params is given the class upon construction * and only the pattern values are given to the method * @return mixed Whatever is returned by the closure or method */ public function dispatch($params = null) { // Process filters if ($this->filter) { foreach ($this->filter as $filter) { if (!Router::hasFilter($filter)) { throw new Exceptions\FailedFilterException("Filter '{$filter}' not registered"); } if (!Router::handleFilter($filter)) { throw new Exceptions\FailedFilterException("Filter '{$filter}' failed"); } } } // Extract variables from URL $vars = $this->getVars($this->url); // Call Closure if available if (!is_null($this->callable)) { if ($params) { array_unshift($vars, $params); } return call_user_func_array($this->callable, $vars); } // If no Closure, instantiate class if (!$this->class || !class_exists($this->class)) { throw new Exceptions\RouteException("Controller '{$this->class}' wasn't found."); } $controller = new $this->class($params); // Call class method if (method_exists($controller, $this->method) && is_callable([$controller, $this->method])) { return call_user_func_array([$controller, $this->method], $vars); } else { throw new Exceptions\RouteException("Method '{$this->method}' wasn't found in Class '{$this->class}' or is not public."); } }