/** * Gets the response from a routed controller. * A page controller is resolved from the given or user requested route path. * The first segment of a route path is always the 'class segment' and * determines which vB_Route is being requested. Class segments are mapped to * actual class names in the table `routes`. The full path is given to the * resolved vB_Route and a response is requested. * * Rerouting recursions are detected and an error thrown when a recursion is * found. If the requested route is identical to the previous route the error * is thrown immediately. If recursive requesting is not consecutive, the * router checks the path trace for previous occurences of the specified route * and throws an error if it has occured more than $infinite_reroute_threshold * times. * * Note: It is up to the client code to catch and handle any exceptions. The * only exception that should intentionally be thrown to here is a reroute * exception which will contain a new route to respond to. * @see class vB_Route * * @param string | vB_Route $route - The route to delegate a controller from * @return vB_Controller - The resolved controller */ public static function getResponse($route = false) { // Save the initial path for debug and errors if (!isset(self::$initial_path)) { self::$initial_path = (string) $route; } // If no route specified, get the user requested route path if (false === $route) { $route = self::getEntryPath(); } // Get the appropriate route for the given path if (!$route instanceof vB_Route) { $route = self::newRoute($route); } if (!self::$validated_friendly_url) { // Check the request matches the friendly url option $route->assertFriendlyUrl(); self::$validated_friendly_url = true; } // Check if new route is the same as the current route if (self::$current_route and (string) $route == (string) self::$current_route) { // prevent recursion throw new vB_Exception_Critical('Rerouting recursion with: ' . (string) $route); } // Detect non consecutive rerouting recursion if (sizeof(self::$path_trace) > 1 and sizeof(array_keys(self::$path_trace, (string) $route)) > self::$infinite_reroute_threshold) { // prevent recursion throw new vB_Exception_Critical('Non Consecutive Rerouting recursion detected with: ' . (string) $route); } // Save initial route for logging and errors if (!self::$initial_route) { self::$initial_route = $route; } // Save current route for recursion prevention, logging and errors self::$current_route = $route; // Add route string to route trace to prevent non consecutive recursion self::$path_trace[] = (string) $route; // Try to delegate a controller and get it's response, catching any reroute exceptions try { // get the response from the routed page controller return $route->getResponse(); } catch (vB_Exception_Reroute $e) { // get the rerouted route $route = self::newRoute($e->getRoutePath()); // save the reroute message $route->setRerouteMessage($e->getMessage()); // get the response for the new route return self::getResponse($route); } catch (vB_Exception $e) { if (vB::$vbulletin->debug) { throw $e; } // get the error response from the current route return self::getResponse(self::$current_route->get500Path()); } }