public function testMatch()
 {
     $request = new SS_HTTPRequest("GET", "admin/crm/add");
     /* When a rule matches, but has no variables, array("_matched" => true) is returned. */
     $this->assertEquals(array("_matched" => true), $request->match('admin/crm', true));
     /* Becasue we shifted admin/crm off the stack, just "add" should be remaining */
     $this->assertEquals("add", $request->remaining());
     $this->assertEquals(array("_matched" => true), $request->match('add', true));
 }
 protected function getHTTPRequest($method = 'GET', $class = 'ApiTest_Book', $id = '', $params = array())
 {
     $request = new SS_HTTPRequest($method, 'api/' . $class . '/' . $id, $params);
     $request->match($this->url_pattern);
     $request->setRouteParams(array('Controller' => 'RESTfulAPI'));
     return $request;
 }
 /**
  * @param SS_HTTPRequest $request
  *
  * @return string|HTMLText
  */
 public function preview(SS_HTTPRequest $request)
 {
     $key = $request->param('Key');
     $token = $request->param('Token');
     /**
      * @var ShareToken $shareToken
      */
     $shareToken = ShareToken::get()->filter('token', $token)->first();
     if (!$shareToken) {
         return $this->errorPage();
     }
     $page = Versioned::get_one_by_stage('SiteTree', 'Stage', sprintf('"SiteTree"."ID" = \'%d\'', $shareToken->PageID));
     $latest = Versioned::get_latest_version('SiteTree', $shareToken->PageID);
     $controller = $this->getControllerFor($page);
     if (!$shareToken->isExpired() && $page->generateKey($shareToken->Token) === $key) {
         Requirements::css(SHAREDRAFTCONTENT_DIR . '/css/top-bar.css');
         // Temporarily un-secure the draft site and switch to draft
         $oldSecured = Session::get('unsecuredDraftSite');
         $oldMode = Versioned::get_reading_mode();
         $restore = function () use($oldSecured, $oldMode) {
             Session::set('unsecuredDraftSite', $oldSecured);
             Versioned::set_reading_mode($oldMode);
         };
         // Process page inside an unsecured draft container
         try {
             Session::set('unsecuredDraftSite', true);
             Versioned::reading_stage('Stage');
             // Create mock request; Simplify request to single top level reqest
             $pageRequest = new SS_HTTPRequest('GET', $page->URLSegment);
             $pageRequest->match('$URLSegment//$Action/$ID/$OtherID', true);
             $rendered = $controller->handleRequest($pageRequest, $this->model);
             // Render draft heading
             $data = new ArrayData(array('Page' => $page, 'Latest' => $latest));
             $include = (string) $data->renderWith('Includes/TopBar');
         } catch (Exception $ex) {
             $restore();
             throw $ex;
         }
         $restore();
         return str_replace('</body>', $include . '</body>', (string) $rendered->getBody());
     } else {
         return $this->errorPage();
     }
 }
 public function handleRequest(SS_HTTPRequest $request, DataModel $model = null)
 {
     self::$is_at_root = true;
     $this->setDataModel($model);
     $this->pushCurrent();
     $this->init();
     if (!($site = Multisites::inst()->getCurrentSiteId())) {
         return $this->httpError(404);
     }
     $page = SiteTree::get()->filter(array('ParentID' => $site, 'URLSegment' => 'home'));
     if (!($page = $page->first())) {
         return $this->httpError(404);
     }
     $request = new SS_HTTPRequest($request->httpMethod(), $page->RelativeLink(), $request->getVars(), $request->postVars());
     $request->match('$URLSegment//$Action', true);
     $front = new MultisitesFrontController();
     $response = $front->handleRequest($request, $model);
     $this->popCurrent();
     return $response;
 }
 public function handleRequest(SS_HTTPRequest $request, DataModel $model)
 {
     // If this is the final portion of the request (i.e. the URL is just /admin), direct to the default panel
     if ($request->allParsed()) {
         $base = $this->config()->url_base;
         $segment = Config::inst()->get($this->config()->default_panel, 'url_segment');
         $this->redirect(Controller::join_links($base, $segment));
         return $this->getResponse();
     } else {
         $rules = self::rules();
         foreach ($rules as $pattern => $controller) {
             if (($arguments = $request->match($pattern, true)) !== false) {
                 $controllerObj = Injector::inst()->create($controller);
                 $controllerObj->setSession($this->session);
                 return $controllerObj->handleRequest($request, $model);
             }
         }
     }
     return $this->httpError(404, 'Not found');
 }
 function routeRequest(SS_HTTPRequest $request)
 {
     // Handle the routing
     $noun = singleton('RESTRoot');
     while (!$request->allParsed()) {
         $matched = false;
         if ($params = $request->match('$Next!', true)) {
             $matched = true;
             $next = $params['Next'];
             try {
                 if (method_exists($noun, 'getItem')) {
                     $noun = $noun->getItem($next);
                 } else {
                     $noun = $noun->{$next};
                 }
             } catch (Exception $e) {
                 if ($e instanceof SS_HTTPResponse_Exception) {
                     throw $e;
                 } elseif ($e instanceof RESTException) {
                     $handler = $this->getHandler($noun);
                     $handler->respondWithError(array('code' => $e->getCode(), 'exception' => $e));
                 } else {
                     $handler = $this->getHandler($noun);
                     $handler->respondWithError(array('code' => 500, 'exception' => $e));
                 }
             }
             if (!$noun) {
                 $this->httpError(404);
             }
         }
         if (!$matched) {
             $this->httpError(404);
         }
     }
     // Find the handler and call
     $handler = $this->getHandler($noun);
     return $handler->handleRequest($request);
 }
Esempio n. 7
0
	/**
	 * Handles URL requests.
	 *
	 *  - ViewableData::handleRequest() iterates through each rule in {@link self::$url_handlers}.
	 *  - If the rule matches, the named method will be called.
	 *  - If there is still more URL to be processed, then handleRequest() 
	 *    is called on the object that that method returns.
	 *
	 * Once all of the URL has been processed, the final result is returned.  
	 * However, if the final result is an array, this
	 * array is interpreted as being additional template data to customise the 
	 * 2nd to last result with, rather than an object
	 * in its own right.  This is most frequently used when a Controller's 
	 * action will return an array of data with which to
	 * customise the controller.
	 * 
	 * @param $request The {@link SS_HTTPRequest} object that is reponsible for distributing URL parsing
	 * @uses SS_HTTPRequest
	 * @uses SS_HTTPRequest->match()
	 * @return SS_HTTPResponse|RequestHandler|string|array
	 */
	function handleRequest(SS_HTTPRequest $request, DataModel $model) {
		// $handlerClass is used to step up the class hierarchy to implement url_handlers inheritance
		$handlerClass = ($this->class) ? $this->class : get_class($this);
	
		if($this->brokenOnConstruct) {
			user_error("parent::__construct() needs to be called on {$handlerClass}::__construct()", E_USER_WARNING);
		}
	
		$this->request = $request;
		$this->setModel($model);
		
		// We stop after RequestHandler; in other words, at ViewableData
		while($handlerClass && $handlerClass != 'ViewableData') {
			$urlHandlers = Config::inst()->get($handlerClass, 'url_handlers', Config::FIRST_SET);

			if($urlHandlers) foreach($urlHandlers as $rule => $action) {
				if(isset($_REQUEST['debug_request'])) Debug::message("Testing '$rule' with '" . $request->remaining() . "' on $this->class");
				if($params = $request->match($rule, true)) {
					// Backwards compatible setting of url parameters, please use SS_HTTPRequest->latestParam() instead
					//Director::setUrlParams($request->latestParams());
				
					if(isset($_REQUEST['debug_request'])) {
						Debug::message("Rule '$rule' matched to action '$action' on $this->class.  Latest request params: " . var_export($request->latestParams(), true));
					}
				
					// Actions can reference URL parameters, eg, '$Action/$ID/$OtherID' => '$Action',
					if($action[0] == '$') $action = $params[substr($action,1)];
				
					if($this->checkAccessAction($action)) {
						if(!$action) {
							if(isset($_REQUEST['debug_request'])) Debug::message("Action not set; using default action method name 'index'");
							$action = "index";
						} else if(!is_string($action)) {
							user_error("Non-string method name: " . var_export($action, true), E_USER_ERROR);
						}
						
						try {
							if(!$this->hasMethod($action)) {
								return $this->httpError(404, "Action '$action' isn't available on class " . get_class($this) . ".");
							}
							$result = $this->$action($request);
						} catch(SS_HTTPResponse_Exception $responseException) {
							$result = $responseException->getResponse();
						}
					} else {
						return $this->httpError(403, "Action '$action' isn't allowed on class " . get_class($this) . ".");
					}
				
					if($result instanceof SS_HTTPResponse && $result->isError()) {
						if(isset($_REQUEST['debug_request'])) Debug::message("Rule resulted in HTTP error; breaking");
						return $result;
					}
				
					// If we return a RequestHandler, call handleRequest() on that, even if there is no more URL to parse.
					// It might have its own handler. However, we only do this if we haven't just parsed an empty rule ourselves,
					// to prevent infinite loops. Also prevent further handling of controller actions which return themselves
					// to avoid infinite loops.
					if($this !== $result && !$request->isEmptyPattern($rule) && is_object($result) && $result instanceof RequestHandler) {
						$returnValue = $result->handleRequest($request, $model);

						// Array results can be used to handle 
						if(is_array($returnValue)) $returnValue = $this->customise($returnValue);
					
						return $returnValue;
						
					// If we return some other data, and all the URL is parsed, then return that
					} else if($request->allParsed()) {
						return $result;
					
					// But if we have more content on the URL and we don't know what to do with it, return an error.
					} else {
						return $this->httpError(404, "I can't handle sub-URLs of a $this->class object.");
					}
				
					return $this;
				}
			}
			
			$handlerClass = get_parent_class($handlerClass);
		}
		
		// If nothing matches, return this object
		return $this;
	}
Esempio n. 8
0
	/**
	 * Custom request handler that will check component handlers before proceeding to the default implementation.
	 * 
	 * @todo There is too much code copied from RequestHandler here.
	 */
	function handleRequest(SS_HTTPRequest $request, DataModel $model) {
		if($this->brokenOnConstruct) {
			user_error("parent::__construct() needs to be called on {$handlerClass}::__construct()", E_USER_WARNING);
		}

		$this->request = $request;
		$this->setModel($model);

		$fieldData = $this->request->requestVar($this->getName());
		if($fieldData && $fieldData['GridState']) $this->getState(false)->setValue($fieldData['GridState']);
		
		foreach($this->components as $component) {
			if(!($component instanceof GridField_URLHandler)) {
				continue;
			}
			
			$urlHandlers = $component->getURLHandlers($this);
			
			if($urlHandlers) foreach($urlHandlers as $rule => $action) {
				if($params = $request->match($rule, true)) {
					// Actions can reference URL parameters, eg, '$Action/$ID/$OtherID' => '$Action',
					if($action[0] == '$') $action = $params[substr($action,1)];
					if(!method_exists($component, 'checkAccessAction') || $component->checkAccessAction($action)) {
						if(!$action) {
							$action = "index";
						} else if(!is_string($action)) {
							throw new LogicException("Non-string method name: " . var_export($action, true));
						}

						try {
							$result = $component->$action($this, $request);
						} catch(SS_HTTPResponse_Exception $responseException) {
							$result = $responseException->getResponse();
						}

						if($result instanceof SS_HTTPResponse && $result->isError()) {
							return $result;
						}

						if($this !== $result && !$request->isEmptyPattern($rule) && is_object($result) && $result instanceof RequestHandler) {
							$returnValue = $result->handleRequest($request, $model);

							if(is_array($returnValue)) {
								throw new LogicException("GridField_URLHandler handlers can't return arrays");
							}

							return $returnValue;

						// If we return some other data, and all the URL is parsed, then return that
						} else if($request->allParsed()) {
							return $result;

						// But if we have more content on the URL and we don't know what to do with it, return an error.
						} else {
							return $this->httpError(404, "I can't handle sub-URLs of a " . get_class($result) . " object.");
						}
					}
				}
			}
		}
		
		return parent::handleRequest($request, $model);
	}
 /**
  * Pass control over to the RequestHandler
  * loop through the handlers provided in config['actions']
  * and find matching url_handlers.
  *
  * $url_handlers rule should not use wildcards like '$Action' => '$Action'
  * but have more specific path defined
  * 
  * @param GridField      $gridField
  * @param SS_HTTPRequest $request
  *
  * @return mixed
  */
 public function handleBulkAction($gridField, $request)
 {
     $controller = $gridField->getForm()->Controller();
     foreach ($this->config['actions'] as $name => $data) {
         $handlerClass = $data['handler'];
         $urlHandlers = Config::inst()->get($handlerClass, 'url_handlers', Config::UNINHERITED);
         if ($urlHandlers) {
             foreach ($urlHandlers as $rule => $action) {
                 if ($request->match($rule, false)) {
                     //print_r('matched ' . $handlerClass . ' to ' . $rule);
                     $handler = Injector::inst()->create($handlerClass, $gridField, $this, $controller);
                     return $handler->handleRequest($request, DataModel::inst());
                 }
             }
         }
     }
     user_error('Unable to find matching bulk action handler for ' . $request->remaining() . '.', E_USER_ERROR);
 }
Esempio n. 10
0
 /**
  * Mock a request against a given controller
  *
  * @param ContentController $controller
  * @param string $url
  */
 protected function requestURL(ContentController $controller, $url)
 {
     $request = new SS_HTTPRequest('get', $url);
     $request->match('$URLSegment//$Action/$ID/$OtherID');
     $request->shift();
     $controller->init();
     $controller->handleRequest($request, new DataModel());
 }
 /**
  * @param SS_HTTPRequest $request
  * @return SS_HTTPResponse
  */
 public function handleRequest(SS_HTTPRequest $request, DataModel $model = null)
 {
     self::$is_at_root = true;
     $this->setDataModel($model);
     $this->pushCurrent();
     $this->init();
     if (!DB::isActive() || !ClassInfo::hasTable('SiteTree')) {
         $this->response = new SS_HTTPResponse();
         $this->response->redirect(Director::absoluteBaseURL() . 'dev/build?returnURL=' . (isset($_GET['url']) ? urlencode($_GET['url']) : null));
         return $this->response;
     }
     $request = new SS_HTTPRequest($request->httpMethod(), self::get_homepage_link() . '/', $request->getVars(), $request->postVars());
     $request->match('$URLSegment//$Action', true);
     $controller = new ModelAsController();
     $result = $controller->handleRequest($request, $model);
     $this->popCurrent();
     return $result;
 }
 function createFakeHTTPRequest($id)
 {
     $r = new SS_HTTPRequest('GET', 'index/' . $id);
     $r->match('index/$ID');
     return $r;
 }
 public function handleRequest(SS_HTTPRequest $request, DataModel $model)
 {
     $this->request = $request;
     if (!$this->authenticate()) {
         return $this->permissionFailure();
     }
     if (!$this->authorize()) {
         return $this->permissionFailure();
     }
     $controller_class = $this->class ? $this->class : get_class($this);
     $url_handlers = Config::inst()->get($controller_class, 'url_handlers', Config::FIRST_SET);
     if ($url_handlers) {
         foreach ($url_handlers as $rule => $action) {
             if ($params = $request->match($rule)) {
                 $res = $this->doBeforeFilter($action, $params);
                 if ($res) {
                     return $res;
                 }
                 break;
             }
         }
     }
     return parent::handleRequest($request, $model);
 }
 /**
  * Handle an HTTP request, defined with a SS_HTTPRequest object.
  *
  * @return SS_HTTPResponse|string
  */
 protected static function handleRequest(SS_HTTPRequest $request, Session $session, DataModel $model)
 {
     $rules = Config::inst()->get('Director', 'rules');
     if (isset($_REQUEST['debug'])) {
         Debug::show($rules);
     }
     foreach ($rules as $pattern => $controllerOptions) {
         if (is_string($controllerOptions)) {
             if (substr($controllerOptions, 0, 2) == '->') {
                 $controllerOptions = array('Redirect' => substr($controllerOptions, 2));
             } else {
                 $controllerOptions = array('Controller' => $controllerOptions);
             }
         }
         if (($arguments = $request->match($pattern, true)) !== false) {
             $request->setRouteParams($controllerOptions);
             // controllerOptions provide some default arguments
             $arguments = array_merge($controllerOptions, $arguments);
             // Find the controller name
             if (isset($arguments['Controller'])) {
                 $controller = $arguments['Controller'];
             }
             // Pop additional tokens from the tokeniser if necessary
             if (isset($controllerOptions['_PopTokeniser'])) {
                 $request->shift($controllerOptions['_PopTokeniser']);
             }
             // Handle redirections
             if (isset($arguments['Redirect'])) {
                 return "redirect:" . Director::absoluteURL($arguments['Redirect'], true);
             } else {
                 Director::$urlParams = $arguments;
                 $controllerObj = Injector::inst()->create($controller);
                 $controllerObj->setSession($session);
                 try {
                     $result = $controllerObj->handleRequest($request, $model);
                 } catch (SS_HTTPResponse_Exception $responseException) {
                     $result = $responseException->getResponse();
                 }
                 if (!is_object($result) || $result instanceof SS_HTTPResponse) {
                     return $result;
                 }
                 user_error("Bad result from url " . $request->getURL() . " handled by " . get_class($controllerObj) . " controller: " . get_class($result), E_USER_WARNING);
             }
         }
     }
     /**
      * @andrelohmann
      * 
      * This code allows to return custom Error Pages without using the CMS Module
      * 
      */
     $template = array('ErrorPage', 'Page');
     $result = new ArrayData(array('Title' => 404, 'Content' => DBField::create_field('HTMLText', 'No URL rule was matched')));
     // No URL rules matched, so return a 404 error.
     return new SS_HTTPResponse($result->renderWith($template), 404);
     /**
      * Original Code
      *
      * // No URL rules matched, so return a 404 error.
      * return new SS_HTTPResponse('No URL rule was matched', 404);
      * 
      */
 }
 public function handleRequest(SS_HTTPRequest $request, DataModel $model)
 {
     if ($request->match('addinlinerecord', true)) {
         // NOTE(Jake): Handling here as I'm not sure how to do a url_handler that allows
         //             infinite parameters after 'addinlinerecord'
         $result = $this->handleAddInline($request);
         if ($result && is_object($result) && $result instanceof RequestHandler) {
             // NOTE(Jake): Logic copied from parent::handleRequest()
             $returnValue = $result->handleRequest($request, $model);
             if ($returnValue && is_array($returnValue)) {
                 $returnValue = $this->customise($returnValue);
             }
             return $returnValue;
         }
         // NOTE(Jake): Consume all remaining parts so that 'RequestHandler::handleRequest'
         //             doesn't hit an error. (Use Case: Getting an error with a GridField::handleRequest)
         // NOTE(Jake): THis is probably due to just CLASSNAME not being consumed/shifted in 'addinlinerecord'
         //             but cbf changing and re-testing everything.
         $dirParts = explode('/', $request->remaining());
         foreach ($dirParts as $dirPart) {
             $request->shift();
         }
         return $result;
     }
     $result = parent::handleRequest($request, $model);
     return $result;
 }
Esempio n. 16
0
 /**
  * Custom request handler that will check component handlers before proceeding to the default
  * implementation.
  *
  * @todo copy less code from RequestHandler.
  *
  * @param SS_HTTPRequest $request
  * @param DataModel $model
  *
  * @return array|RequestHandler|SS_HTTPResponse|string|void
  *
  * @throws SS_HTTPResponse_Exception
  */
 public function handleRequest(SS_HTTPRequest $request, DataModel $model)
 {
     if ($this->brokenOnConstruct) {
         user_error(sprintf("parent::__construct() needs to be called on %s::__construct()", __CLASS__), E_USER_WARNING);
     }
     $this->request = $request;
     $this->setDataModel($model);
     $fieldData = $this->request->requestVar($this->getName());
     if ($fieldData && isset($fieldData['GridState'])) {
         $this->getState(false)->setValue($fieldData['GridState']);
     }
     foreach ($this->getComponents() as $component) {
         if ($component instanceof GridField_URLHandler && ($urlHandlers = $component->getURLHandlers($this))) {
             foreach ($urlHandlers as $rule => $action) {
                 if ($params = $request->match($rule, true)) {
                     // Actions can reference URL parameters.
                     // e.g. '$Action/$ID/$OtherID' → '$Action'
                     if ($action[0] == '$') {
                         $action = $params[substr($action, 1)];
                     }
                     if (!method_exists($component, 'checkAccessAction') || $component->checkAccessAction($action)) {
                         if (!$action) {
                             $action = "index";
                         }
                         if (!is_string($action)) {
                             throw new LogicException(sprintf('Non-string method name: %s', var_export($action, true)));
                         }
                         try {
                             $result = $component->{$action}($this, $request);
                         } catch (SS_HTTPResponse_Exception $responseException) {
                             $result = $responseException->getResponse();
                         }
                         if ($result instanceof SS_HTTPResponse && $result->isError()) {
                             return $result;
                         }
                         if ($this !== $result && !$request->isEmptyPattern($rule) && is_object($result) && $result instanceof RequestHandler) {
                             $returnValue = $result->handleRequest($request, $model);
                             if (is_array($returnValue)) {
                                 throw new LogicException('GridField_URLHandler handlers can\'t return arrays');
                             }
                             return $returnValue;
                         }
                         if ($request->allParsed()) {
                             return $result;
                         }
                         return $this->httpError(404, sprintf('I can\'t handle sub-URLs of a %s object.', get_class($result)));
                     }
                 }
             }
         }
     }
     return parent::handleRequest($request, $model);
 }
 /**
  * Handle an HTTP request, defined with a SS_HTTPRequest object.
  *
  * @param SS_HTTPRequest $request
  * @param Session $session
  * @param DataModel $model
  *
  * @return SS_HTTPResponse|string
  */
 protected static function handleRequest(SS_HTTPRequest $request, Session $session, DataModel $model)
 {
     $rules = Config::inst()->get('Director', 'rules');
     if (isset($_REQUEST['debug'])) {
         Debug::show($rules);
     }
     foreach ($rules as $pattern => $controllerOptions) {
         if (is_string($controllerOptions)) {
             if (substr($controllerOptions, 0, 2) == '->') {
                 $controllerOptions = array('Redirect' => substr($controllerOptions, 2));
             } else {
                 $controllerOptions = array('Controller' => $controllerOptions);
             }
         }
         if (($arguments = $request->match($pattern, true)) !== false) {
             $request->setRouteParams($controllerOptions);
             // controllerOptions provide some default arguments
             $arguments = array_merge($controllerOptions, $arguments);
             // Find the controller name
             if (isset($arguments['Controller'])) {
                 $controller = $arguments['Controller'];
             }
             // Pop additional tokens from the tokenizer if necessary
             if (isset($controllerOptions['_PopTokeniser'])) {
                 $request->shift($controllerOptions['_PopTokeniser']);
             }
             // Handle redirection
             if (isset($arguments['Redirect'])) {
                 return "redirect:" . Director::absoluteURL($arguments['Redirect'], true);
             } else {
                 Director::$urlParams = $arguments;
                 $controllerObj = Injector::inst()->create($controller);
                 $controllerObj->setSession($session);
                 try {
                     $result = $controllerObj->handleRequest($request, $model);
                 } catch (SS_HTTPResponse_Exception $responseException) {
                     $result = $responseException->getResponse();
                 }
                 if (!is_object($result) || $result instanceof SS_HTTPResponse) {
                     return $result;
                 }
                 user_error("Bad result from url " . $request->getURL() . " handled by " . get_class($controllerObj) . " controller: " . get_class($result), E_USER_WARNING);
             }
         }
     }
     // No URL rules matched, so return a 404 error.
     return new SS_HTTPResponse('No URL rule was matched', 404);
 }
 public function handleRequest(SS_HTTPRequest $request, DataModel $model = null)
 {
     self::$is_at_root = true;
     $this->setDataModel($model);
     $this->pushCurrent();
     $this->init();
     if ($language = $request->param('Language')) {
         if (Config::inst()->get('MultilingualRootURLController', 'UseLocaleURL')) {
             if (Config::inst()->get('MultilingualRootURLController', 'UseDashLocale')) {
                 //Language is missing a dash 404
                 if (strpos($language, '-') === false) {
                     //Locale not found 404
                     if ($response = ErrorPage::response_for(404)) {
                         return $response;
                     } else {
                         $this->httpError(404, 'The requested page could not be found.');
                     }
                     return $this->response;
                 }
                 $locale = explode('-', $language);
                 $locale[1] = strtoupper($locale[1]);
                 //Make sure that the language is all lowercase
                 if ($language == implode('-', $locale)) {
                     //Locale not found 404
                     if ($response = ErrorPage::response_for(404)) {
                         return $response;
                     } else {
                         $this->httpError(404, 'The requested page could not be found.');
                     }
                     return $this->response;
                 }
                 $locale = implode('_', $locale);
             } else {
                 $locale = $language;
             }
         } else {
             if (strpos($request->param('Language'), '_') !== false) {
                 //Locale not found 404
                 if ($response = ErrorPage::response_for(404)) {
                     return $response;
                 } else {
                     $this->httpError(404, 'The requested page could not be found.');
                 }
                 return $this->response;
             } else {
                 $locale = i18n::get_locale_from_lang($language);
             }
         }
         if (in_array($locale, Translatable::get_allowed_locales())) {
             Cookie::set('language', $language);
             Translatable::set_current_locale($locale);
             i18n::set_locale($locale);
             if (!DB::isActive() || !ClassInfo::hasTable('SiteTree')) {
                 $this->response = new SS_HTTPResponse();
                 $this->response->redirect(Director::absoluteBaseURL() . 'dev/build?returnURL=' . (isset($_GET['url']) ? urlencode($_GET['url']) : null));
                 return $this->response;
             }
             $request->setUrl($language . '/' . self::get_homepage_link() . '/');
             $request->match('$Language/$URLSegment//$Action', true);
             $controller = new MultilingualModelAsController();
             $result = $controller->handleRequest($request, $model);
             $this->popCurrent();
             return $result;
         } else {
             //URL Param Locale is not allowed so redirect to default
             $this->redirect(Controller::join_links(Director::baseURL(), Config::inst()->get('MultilingualRootURLController', 'UseLocaleURL') ? Translatable::default_locale() : Translatable::default_lang()) . '/', 301);
             $this->popCurrent();
             return $this->response;
         }
     }
     //No Locale Param so detect browser language and redirect
     if ($locale = self::detect_browser_locale()) {
         if (Config::inst()->get('MultilingualRootURLController', 'UseLocaleURL')) {
             if (Config::inst()->get('MultilingualRootURLController', 'UseDashLocale')) {
                 $language = str_replace('_', '-', strtolower($locale));
             } else {
                 $language = $locale;
             }
         } else {
             $language = i18n::get_lang_from_locale($locale);
         }
         Cookie::set('language', $language);
         $this->redirect(Controller::join_links(Director::baseURL(), $language) . '/', 301);
         $this->popCurrent();
         return $this->response;
     }
     if (Config::inst()->get('MultilingualRootURLController', 'UseLocaleURL')) {
         if (Config::inst()->get('MultilingualRootURLController', 'UseDashLocale')) {
             $language = str_replace('_', '-', strtolower(Translatable::default_locale()));
         } else {
             $language = Translatable::default_locale();
         }
     } else {
         $language = Translatable::default_lang();
     }
     $this->redirect(Controller::join_links(Director::baseURL(), $language . '/'), 301);
     $this->popCurrent();
     return $this->response;
 }
 /**
  * @param SS_HTTPRequest $request
  * @return array
  */
 protected function findAction($request)
 {
     $handlerClass = $this->class ? $this->class : get_class($this);
     // We stop after RequestHandler; in other words, at ViewableData
     while ($handlerClass && $handlerClass != 'ViewableData') {
         $urlHandlers = Config::inst()->get($handlerClass, 'url_handlers', Config::UNINHERITED);
         if ($urlHandlers) {
             foreach ($urlHandlers as $rule => $action) {
                 if (isset($_REQUEST['debug_request'])) {
                     Debug::message("Testing '{$rule}' with '" . $request->remaining() . "' on {$this->class}");
                 }
                 if ($request->match($rule, true)) {
                     if (isset($_REQUEST['debug_request'])) {
                         Debug::message("Rule '{$rule}' matched to action '{$action}' on {$this->class}. " . "Latest request params: " . var_export($request->latestParams(), true));
                     }
                     return array('rule' => $rule, 'action' => $action);
                 }
             }
         }
         $handlerClass = get_parent_class($handlerClass);
     }
 }
 /**
  * Generates a fake request for the field
  * @param {SS_HTTPRequest} $request Source Request to base the fake request off of
  * @param {Widget} $sourceWidget Source widget
  * @param {string} $baseLink Base URL to be truncated off of the form
  * @return {SS_HTTPRequest} Fake HTTP Request used to fool the form field into thinking the request was made to it directly
  */
 protected function getFakeRequest(SS_HTTPRequest $request, Widget $sourceWidget, $baseLink)
 {
     $fieldName = rawurldecode($request->param('FieldName'));
     $objID = preg_replace('/Widget\\[(.*?)\\]\\[(.*?)\\]\\[(.*?)\\]$/', '$2', $fieldName);
     $finalPostVars = array();
     if ($request->isPOST()) {
         $postVars = $request->postVars();
         //Pull the post data for the widget
         if (isset($postVars['Widget'][$this->getName()][$objID])) {
             $finalPostVars = $postVars['Widget'][$this->getName()][$objID];
         } else {
             $finalPostVars = array();
         }
         $finalPostVars = array_merge($finalPostVars, $postVars);
         unset($finalPostVars['Widget']);
         //Workaround for UploadField's and GridFields confusing the request
         $fields = $sourceWidget->getCMSFields();
         $uploadFields = array();
         $gridFields = array();
         foreach ($fields as $field) {
             if ($field instanceof UploadField) {
                 $uploadFields[] = $field->getName();
             } else {
                 if ($field instanceof GridField) {
                     $gridFields[] = $field->getName();
                 }
             }
         }
         //Re-orgazine the upload field data
         if (count($uploadFields)) {
             foreach ($uploadFields as $field) {
                 $formFieldName = 'Widget[' . $this->getName() . '][' . $objID . '][' . $field . ']';
                 $fieldData = array($formFieldName => array('name' => array('Uploads' => array()), 'type' => array('Uploads' => array()), 'tmp_name' => array('Uploads' => array()), 'error' => array('Uploads' => array()), 'size' => array('Uploads' => array())));
                 if (isset($postVars['Widget']['name'][$this->getName()][$objID][$field]['Uploads'])) {
                     for ($i = 0; $i < count($postVars['Widget']['name'][$this->getName()][$objID][$field]['Uploads']); $i++) {
                         $fieldData[$formFieldName]['name']['Uploads'][] = $postVars['Widget']['name'][$this->getName()][$objID][$field]['Uploads'][$i];
                         $fieldData[$formFieldName]['type']['Uploads'][] = $postVars['Widget']['type'][$this->getName()][$objID][$field]['Uploads'][$i];
                         $fieldData[$formFieldName]['tmp_name']['Uploads'][] = $postVars['Widget']['tmp_name'][$this->getName()][$objID][$field]['Uploads'][$i];
                         $fieldData[$formFieldName]['error']['Uploads'][] = $postVars['Widget']['error'][$this->getName()][$objID][$field]['Uploads'][$i];
                         $fieldData[$formFieldName]['size']['Uploads'][] = $postVars['Widget']['size'][$this->getName()][$objID][$field]['Uploads'][$i];
                     }
                 }
                 $finalPostVars = array_merge_recursive($finalPostVars, $fieldData);
             }
         }
         //Reorganize the gridfield data
         if (count($gridFields) && isset($postVars['Widget'][$this->getName()][$objID])) {
             foreach ($gridFields as $field) {
                 $formFieldName = 'Widget[' . $this->getName() . '][' . $objID . '][' . $field . ']';
                 $fieldData = array($formFieldName => $postVars['Widget'][$this->getName()][$objID][$field]);
             }
             $finalPostVars = array_merge_recursive($finalPostVars, $fieldData);
         }
     }
     $headers = $request->getHeaders();
     $request = new SS_HTTPRequest($_SERVER['REQUEST_METHOD'], str_replace(rtrim($baseLink, '/'), '', rtrim($request->getURL(), '/')) . '/', $request->getVars(), $finalPostVars, $request->getBody());
     $request->match('$Action/$ID/$OtherID');
     //Merge in the headers
     foreach ($headers as $header => $value) {
         $request->addHeader($header, $value);
     }
     return $request;
 }