/**
  * @param \SS_HTTPRequest $request
  * @return null|\SS_HTTPResponse
  */
 public function getResponse(\SS_HTTPRequest $request)
 {
     if ($redirect = $this->getRedirectForRequest($request)) {
         $response = new \SS_HTTPResponse();
         $response->redirect($redirect->getTo(), $redirect->getStatusCode());
         return $response;
     }
     return null;
 }
 /**
  * Redirct to the given URL.
  * It is generally recommended to call Director::redirect() rather than calling this function directly.
  */
 function redirect($url, $code = 302)
 {
     if ($this->response->getHeader('Location')) {
         user_error("Already directed to " . $this->response->getHeader('Location') . "; now trying to direct to {$url}", E_USER_WARNING);
         return;
     }
     // Attach site-root to relative links, if they have a slash in them
     if ($url == "" || $url[0] == '?' || substr($url, 0, 4) != "http" && $url[0] != "/" && strpos($url, '/') !== false) {
         $url = Director::baseURL() . $url;
     }
     $this->response->redirect($url, $code);
 }
 /**
  * @param SS_HTTPRequest $request
  * @throws SS_HTTPResponse_Exception
  */
 public function onBeforeHTTPError404($request)
 {
     $url = strtolower($this->getUrl($request));
     $oldPage = OldURLRedirect::get_from_url($url);
     // If there's a match, direct!
     if ($oldPage) {
         $response = new SS_HTTPResponse();
         $dest = $oldPage->getRedirectionLink();
         $response->redirect(Director::absoluteURL($dest), $oldPage->getRedirectCode());
         throw new SS_HTTPResponse_Exception($response);
     }
 }
 /**
  * Process all incoming requests passed to this controller, checking
  * that the file exists and passing the file through if possible.
  */
 public function handleRequest(SS_HTTPRequest $request, DataModel $model)
 {
     $response = new SS_HTTPResponse();
     $filename = $request->getURL();
     if (strpos($filename, 'cdnassets') === 0) {
         $filename = 'assets/' . substr($filename, strlen('cdnassets/'));
     }
     $file = null;
     if (strpos($filename, '_resampled') !== false) {
         $file = ContentServiceAsset::get()->filter('Filename', $filename)->first();
     } else {
         if (strpos($filename, '/_versions/') !== false) {
             $file = FileVersion::get()->filter('Filename', "/" . $filename)->first();
         } else {
             $file = File::get()->filter('filename', $filename)->first();
         }
     }
     if ($file && $file->canView()) {
         if (!$file->CDNFile && !$file->FilePointer) {
             return $this->httpError(404);
         }
         // Permission passed redirect to file
         $redirectLink = '';
         if ($file->getViewType() != CDNFile::ANYONE_PERM) {
             if ($file->hasMethod('getSecureURL')) {
                 $redirectLink = $file->getSecureURL(180);
             }
             if (!strlen($redirectLink)) {
                 // can we stream it?
                 return $this->sendFile($file);
             }
         } else {
             $redirectLink = $file->getURL();
         }
         if ($redirectLink && trim($redirectLink, '/') != $request->getURL()) {
             $response->redirect($redirectLink);
         } else {
             return $this->httpError(404);
         }
     } else {
         if (class_exists('SecureFileController')) {
             $handoff = SecureFileController::create();
             return $handoff->handleRequest($request, $model);
         } elseif ($file instanceof File) {
             // Permission failure
             Security::permissionFailure($this, 'You are not authorised to access this resource. Please log in.');
         } else {
             // File doesn't exist
             $response = new SS_HTTPResponse('File Not Found', 404);
         }
     }
     return $response;
 }
 /**
  * On every URL that generates a 404, we'll capture it here and see if we can
  * find an old URL that it should be redirecting to.
  *
  * @param SS_HTTPResponse $request The request object
  * @throws SS_HTTPResponse_Exception
  */
 public function onBeforeHTTPError404($request)
 {
     // We need to get the URL ourselves because $request->allParams() only has a max of 4 params
     $params = preg_split('|/+|', $request->getURL());
     $getvars = $request->getVars();
     unset($getvars['url']);
     $page = self::find_old_page($params);
     if ($page) {
         $res = new SS_HTTPResponse();
         $res->redirect(Controller::join_links($page, $getvars ? '?' . http_build_query($getvars) : null), 301);
         throw new SS_HTTPResponse_Exception($res);
     }
 }
 /**
  * On every URL that generates a 404, we'll capture it here and see if we can
  * find an old URL that it should be redirecting to.
  *
  * @param SS_HTTPResponse $request The request object
  * @throws SS_HTTPResponse_Exception
  */
 public function onBeforeHTTPError404($request)
 {
     // Build up the request parameters
     $params = array_filter(array_values($request->allParams()), function ($v) {
         return $v !== NULL;
     });
     $getvars = $request->getVars();
     unset($getvars['url']);
     $page = self::find_old_page($params);
     if ($page) {
         $res = new SS_HTTPResponse();
         $res->redirect(Controller::join_links($page, $getvars ? '?' . http_build_query($getvars) : null), 301);
         throw new SS_HTTPResponse_Exception($res);
     }
 }
 /**
  * On every URL that generates a 404, we'll capture it here and see if we can
  * find an old URL that it should be redirecting to.
  *
  * @param SS_HTTPRequest $request The request object
  * @throws SS_HTTPResponse_Exception
  */
 public function onBeforeHTTPError404($request)
 {
     // We need to get the URL ourselves because $request->allParams() only has a max of 4 params
     $params = preg_split('|/+|', $request->getURL());
     $cleanURL = trim(Director::makeRelative($request->getURL(false), '/'));
     $getvars = $request->getVars();
     unset($getvars['url']);
     $page = self::find_old_page($params);
     $cleanPage = trim(Director::makeRelative($page), '/');
     if (!$cleanPage) {
         $cleanPage = Director::makeRelative(RootURLController::get_homepage_link());
     }
     if ($page && $cleanPage != $cleanURL) {
         $res = new SS_HTTPResponse();
         $res->redirect(Controller::join_links($page, $getvars ? '?' . http_build_query($getvars) : null), 301);
         throw new SS_HTTPResponse_Exception($res);
     }
 }
 /**
  * @return SS_HTTPResponse
  */
 public function onBeforeInit()
 {
     $config = SiteConfig::current_site_config();
     // If Maintenance Mode is Off, skip processing
     if (!$config->MaintenanceMode) {
         return;
     }
     // Check if the visitor is Admin OR if they have an allowed IP.
     if (Permission::check('VIEW_SITE_MAINTENANCE_MODE') || Permission::check('ADMIN') || $this->hasAllowedIP()) {
         return;
     }
     // Are we already on the UtilityPage? If so, skip processing.
     if ($this->owner instanceof UtilityPage_Controller) {
         return;
     }
     // Fetch our utility page instance now.
     /**
      * @var Page $utilityPage
      */
     $utilityPage = UtilityPage::get()->first();
     if (!$utilityPage) {
         return;
     }
     // We need a utility page before we can do anything.
     // Are we configured to prevent redirection to the UtilityPage URL?
     if ($utilityPage->config()->DisableRedirect) {
         // Process the request internally to ensure that the URL is maintained
         // (instead of redirecting to the maintenance page's URL) and skip any further processing.
         $controller = ModelAsController::controller_for($utilityPage);
         $response = $controller->handleRequest(new SS_HTTPRequest('GET', ''), DataModel::inst());
         HTTP::add_cache_headers($response);
         $response->output();
         die;
     }
     // Default: Skip any further processing and immediately respond with a redirect to the UtilityPage.
     $response = new SS_HTTPResponse();
     $response->redirect($utilityPage->AbsoluteLink(), 302);
     HTTP::add_cache_headers($response);
     $response->output();
     die;
 }
Exemple #9
0
 /**
  * Test a URL request, returning a response object.
  * 
  * This method is the counterpart of Director::direct() that is used in functional testing.  It will execute the
  * URL given, and return the result as an SS_HTTPResponse object.
  * 
  * @param string $url The URL to visit
  * @param array $postVars The $_POST & $_FILES variables
  * @param Session $session The {@link Session} object representing the current session.  By passing the same
  *                         object to multiple  calls of Director::test(), you can simulate a persisted session.
  * @param string $httpMethod The HTTP method, such as GET or POST.  It will default to POST if postVars is set,
  *                           GET otherwise. Overwritten by $postVars['_method'] if present.
  * @param string $body The HTTP body
  * @param array $headers HTTP headers with key-value pairs
  * @param array $cookies to populate $_COOKIE
  * @param HTTP_Request $request The {@see HTTP_Request} object generated as a part of this request
  * @return SS_HTTPResponse
  * 
  * @uses getControllerForURL() The rule-lookup logic is handled by this.
  * @uses Controller::run() Controller::run() handles the page logic for a Director::direct() call.
  */
 public static function test($url, $postVars = null, $session = null, $httpMethod = null, $body = null, $headers = null, $cookies = null, &$request = null)
 {
     Config::nest();
     // These are needed so that calling Director::test() doesnt muck with whoever is calling it.
     // Really, it's some inappropriate coupling and should be resolved by making less use of statics
     $oldStage = Versioned::current_stage();
     $getVars = array();
     if (!$httpMethod) {
         $httpMethod = $postVars || is_array($postVars) ? "POST" : "GET";
     }
     if (!$session) {
         $session = new Session(null);
     }
     // Back up the current values of the superglobals
     $existingRequestVars = isset($_REQUEST) ? $_REQUEST : array();
     $existingGetVars = isset($_GET) ? $_GET : array();
     $existingPostVars = isset($_POST) ? $_POST : array();
     $existingSessionVars = isset($_SESSION) ? $_SESSION : array();
     $existingCookies = isset($_COOKIE) ? $_COOKIE : array();
     $existingServer = isset($_SERVER) ? $_SERVER : array();
     $existingRequirementsBackend = Requirements::backend();
     Config::inst()->update('Cookie', 'report_errors', false);
     Requirements::set_backend(new Requirements_Backend());
     // Handle absolute URLs
     if (@parse_url($url, PHP_URL_HOST) != '') {
         $bits = parse_url($url);
         $_SERVER['HTTP_HOST'] = $bits['host'];
         $url = Director::makeRelative($url);
     }
     $urlWithQuerystring = $url;
     if (strpos($url, '?') !== false) {
         list($url, $getVarsEncoded) = explode('?', $url, 2);
         parse_str($getVarsEncoded, $getVars);
     }
     // Replace the superglobals with appropriate test values
     $_REQUEST = ArrayLib::array_merge_recursive((array) $getVars, (array) $postVars);
     $_GET = (array) $getVars;
     $_POST = (array) $postVars;
     $_SESSION = $session ? $session->inst_getAll() : array();
     $_COOKIE = (array) $cookies;
     $_SERVER['REQUEST_URI'] = Director::baseURL() . $urlWithQuerystring;
     $request = new SS_HTTPRequest($httpMethod, $url, $getVars, $postVars, $body);
     if ($headers) {
         foreach ($headers as $k => $v) {
             $request->addHeader($k, $v);
         }
     }
     // Pre-request filtering
     // @see issue #2517
     $model = DataModel::inst();
     $output = Injector::inst()->get('RequestProcessor')->preRequest($request, $session, $model);
     if ($output === false) {
         // @TODO Need to NOT proceed with the request in an elegant manner
         throw new SS_HTTPResponse_Exception(_t('Director.INVALID_REQUEST', 'Invalid request'), 400);
     }
     // TODO: Pass in the DataModel
     $result = Director::handleRequest($request, $session, $model);
     // Ensure that the result is an SS_HTTPResponse object
     if (is_string($result)) {
         if (substr($result, 0, 9) == 'redirect:') {
             $response = new SS_HTTPResponse();
             $response->redirect(substr($result, 9));
             $result = $response;
         } else {
             $result = new SS_HTTPResponse($result);
         }
     }
     $output = Injector::inst()->get('RequestProcessor')->postRequest($request, $result, $model);
     if ($output === false) {
         throw new SS_HTTPResponse_Exception("Invalid response");
     }
     // Restore the superglobals
     $_REQUEST = $existingRequestVars;
     $_GET = $existingGetVars;
     $_POST = $existingPostVars;
     $_SESSION = $existingSessionVars;
     $_COOKIE = $existingCookies;
     $_SERVER = $existingServer;
     Requirements::set_backend($existingRequirementsBackend);
     // These are needed so that calling Director::test() doesnt muck with whoever is calling it.
     // Really, it's some inappropriate coupling and should be resolved by making less use of statics
     Versioned::reading_stage($oldStage);
     Config::unnest();
     return $result;
 }
Exemple #10
0
 /**
  * Process the given URL, creating the appropriate controller and executing it.
  * 
  * Request processing is handled as follows:
  *  - Director::direct() creates a new SS_HTTPResponse object and passes this to Director::handleRequest().
  *  - Director::handleRequest($request) checks each of the Director rules and identifies a controller to handle this 
  *    request.
  *  - Controller::handleRequest($request) is then called.  This will find a rule to handle the URL, and call the rule
  *    handling method.
  *  - RequestHandler::handleRequest($request) is recursively called whenever a rule handling method returns a
  *    RequestHandler object.
  *
  * In addition to request processing, Director will manage the session, and perform the output of the actual response
  * to the browser.
  * 
  * @param $url String, the URL the user is visiting, without the querystring.
  * @uses handleRequest() rule-lookup logic is handled by this.
  * @uses Controller::run() Controller::run() handles the page logic for a Director::direct() call.
  */
 static function direct($url)
 {
     // Validate $_FILES array before merging it with $_POST
     foreach ($_FILES as $k => $v) {
         if (is_array($v['tmp_name'])) {
             $v = ArrayLib::array_values_recursive($v['tmp_name']);
             foreach ($v as $tmpFile) {
                 if ($tmpFile && !is_uploaded_file($tmpFile)) {
                     user_error("File upload '{$k}' doesn't appear to be a valid upload", E_USER_ERROR);
                 }
             }
         } else {
             if ($v['tmp_name'] && !is_uploaded_file($v['tmp_name'])) {
                 user_error("File upload '{$k}' doesn't appear to be a valid upload", E_USER_ERROR);
             }
         }
     }
     $req = new SS_HTTPRequest(isset($_SERVER['X-HTTP-Method-Override']) ? $_SERVER['X-HTTP-Method-Override'] : $_SERVER['REQUEST_METHOD'], $url, $_GET, array_merge((array) $_POST, (array) $_FILES), @file_get_contents('php://input'));
     // @todo find better way to extract HTTP headers
     if (isset($_SERVER['HTTP_ACCEPT'])) {
         $req->addHeader("Accept", $_SERVER['HTTP_ACCEPT']);
     }
     if (isset($_SERVER['CONTENT_TYPE'])) {
         $req->addHeader("Content-Type", $_SERVER['CONTENT_TYPE']);
     }
     if (isset($_SERVER['HTTP_REFERER'])) {
         $req->addHeader("Referer", $_SERVER['HTTP_REFERER']);
     }
     // Load the session into the controller
     $session = new Session(isset($_SESSION) ? $_SESSION : null);
     $result = Director::handleRequest($req, $session);
     $session->inst_save();
     // Return code for a redirection request
     if (is_string($result) && substr($result, 0, 9) == 'redirect:') {
         $response = new SS_HTTPResponse();
         $response->redirect(substr($result, 9));
         $response->output();
         // Handle a controller
     } else {
         if ($result) {
             if ($result instanceof SS_HTTPResponse) {
                 $response = $result;
             } else {
                 $response = new SS_HTTPResponse();
                 $response->setBody($result);
             }
             // ?debug_memory=1 will output the number of bytes of memory used for this request
             if (isset($_REQUEST['debug_memory']) && $_REQUEST['debug_memory']) {
                 Debug::message(sprintf("Peak memory usage in bytes: %s", number_format(memory_get_peak_usage(), 0)));
             } else {
                 $response->output();
             }
             //$controllerObj->getSession()->inst_save();
         }
     }
 }
<?php

global $project;
$project = 'mysite';
// use the _ss_environment.php file for configuration
require_once 'conf/ConfigureFromEnv.php';
// set default language
i18n::set_locale('en_US');
define('PROJECT_THIRDPARTY_DIR', project() . '/thirdparty');
define('PROJECT_THIRDPARTY_PATH', BASE_PATH . '/' . PROJECT_THIRDPARTY_DIR);
if (SS_IS_TEST_ENV) {
    BasicAuth::protect_entire_site(true);
}
if (Director::isLive()) {
    if (strpos(Director::absoluteBaseURL(), 'silverstripe-europe.org') !== false || strpos(Director::absoluteBaseURL(), 'www') !== false) {
        $response = new SS_HTTPResponse();
        $response->redirect('https://stripecon.eu', 301);
        HTTP::add_cache_headers($response);
        $response->output();
        die;
    }
    // we are in live mode, send errors per email, set cache and force WWW
    HTTP::set_cache_age(3600);
    // HTTP Header for CloudFlare Caching
    SS_Cache::set_cache_lifetime('any', 10800);
    // Serverside cache to 3 hours.
    SS_Log::add_writer(new SS_LogEmailWriter('*****@*****.**'), SS_Log::ERR);
}
Config::inst()->update('HtmlEditorField', 'use_gzip', false);
Exemple #12
0
 /**
  * Process the given URL, creating the appropriate controller and executing it.
  * 
  * Request processing is handled as follows:
  *  - Director::direct() creates a new SS_HTTPResponse object and passes this to Director::handleRequest().
  *  - Director::handleRequest($request) checks each of the Director rules and identifies a controller to handle this 
  *    request.
  *  - Controller::handleRequest($request) is then called.  This will find a rule to handle the URL, and call the rule
  *    handling method.
  *  - RequestHandler::handleRequest($request) is recursively called whenever a rule handling method returns a
  *    RequestHandler object.
  *
  * In addition to request processing, Director will manage the session, and perform the output of the actual response
  * to the browser.
  * 
  * @param $url String, the URL the user is visiting, without the querystring.
  * @uses handleRequest() rule-lookup logic is handled by this.
  * @uses Controller::run() Controller::run() handles the page logic for a Director::direct() call.
  */
 static function direct($url, DataModel $model)
 {
     // Validate $_FILES array before merging it with $_POST
     foreach ($_FILES as $k => $v) {
         if (is_array($v['tmp_name'])) {
             $v = ArrayLib::array_values_recursive($v['tmp_name']);
             foreach ($v as $tmpFile) {
                 if ($tmpFile && !is_uploaded_file($tmpFile)) {
                     user_error("File upload '{$k}' doesn't appear to be a valid upload", E_USER_ERROR);
                 }
             }
         } else {
             if ($v['tmp_name'] && !is_uploaded_file($v['tmp_name'])) {
                 user_error("File upload '{$k}' doesn't appear to be a valid upload", E_USER_ERROR);
             }
         }
     }
     $req = new SS_HTTPRequest(isset($_SERVER['X-HTTP-Method-Override']) ? $_SERVER['X-HTTP-Method-Override'] : $_SERVER['REQUEST_METHOD'], $url, $_GET, array_merge((array) $_POST, (array) $_FILES), @file_get_contents('php://input'));
     // Load the request headers. If we're not running on Apache, then we
     // need to manually extract the headers from the $_SERVER array.
     if (function_exists('apache_request_headers')) {
         $headers = apache_request_headers();
     } else {
         $headers = self::extract_request_headers($_SERVER);
     }
     foreach ($headers as $header => $value) {
         $req->addHeader($header, $value);
     }
     // Load the session into the controller
     $session = new Session(isset($_SESSION) ? $_SESSION : null);
     $result = Director::handleRequest($req, $session, $model);
     $session->inst_save();
     // Return code for a redirection request
     if (is_string($result) && substr($result, 0, 9) == 'redirect:') {
         $response = new SS_HTTPResponse();
         $response->redirect(substr($result, 9));
         $response->output();
         // Handle a controller
     } else {
         if ($result) {
             if ($result instanceof SS_HTTPResponse) {
                 $response = $result;
             } else {
                 $response = new SS_HTTPResponse();
                 $response->setBody($result);
             }
             // ?debug_memory=1 will output the number of bytes of memory used for this request
             if (isset($_REQUEST['debug_memory']) && $_REQUEST['debug_memory']) {
                 Debug::message(sprintf("Peak memory usage in bytes: %s", number_format(memory_get_peak_usage(), 0)));
             } else {
                 $response->output();
             }
             //$controllerObj->getSession()->inst_save();
         }
     }
 }
 public function RedirectToPage($url)
 {
     $response = new SS_HTTPResponse();
     $response->redirect($url, 301);
     throw new SS_HTTPResponse_Exception($response);
 }
 /**
  *	Determine whether a media page child once existed for the current request, and redirect appropriately.
  *
  *	@return ss http response
  */
 private function resolveURL()
 {
     // Retrieve the current request URL segments.
     $request = $this->getRequest();
     $URL = $request->getURL();
     $holder = substr($URL, 0, strpos($URL, '/'));
     $page = substr($URL, strrpos($URL, '/') + 1);
     // Determine whether a media page child once existed.
     $resolution = self::find_old_page(array($holder, $page));
     $comparison = trim($resolution, '/');
     // Make sure the current request URL doesn't match the resolution.
     if ($resolution && $page !== substr($comparison, strrpos($comparison, '/') + 1)) {
         // Retrieve the current request parameters.
         $parameters = $request->getVars();
         unset($parameters['url']);
         // Appropriately redirect towards the updated media page URL.
         $response = new SS_HTTPResponse();
         return $response->redirect(self::join_links($resolution, !empty($parameters) ? '?' . http_build_query($parameters) : null), 301);
     } else {
         // The media page child doesn't resolve.
         return null;
     }
 }
 /**
  * This acts the same as {@link Controller::handleRequest()}, but if an action cannot be found this will attempt to
  * fall over to a child controller in order to provide functionality for nested URLs.
  *
  * @return SS_HTTPResponse
  */
 public function handleRequest(SS_HTTPRequest $request)
 {
     $child = null;
     $action = $request->param('Action');
     // If nested URLs are enabled, and there is no action handler for the current request then attempt to pass
     // control to a child controller. This allows for the creation of chains of controllers which correspond to a
     // nested URL.
     if ($action && SiteTree::nested_urls() && !$this->hasAction($action)) {
         // See ModelAdController->getNestedController() for similar logic
         Translatable::disable_locale_filter();
         // look for a page with this URLSegment
         $child = DataObject::get_one('SiteTree', sprintf("\"ParentID\" = %s AND \"URLSegment\" = '%s'", $this->ID, Convert::raw2sql($action)));
         Translatable::enable_locale_filter();
         // if we can't find a page with this URLSegment try to find one that used to have
         // that URLSegment but changed. See ModelAsController->getNestedController() for similiar logic.
         if (!$child) {
             $child = ModelAsController::find_old_page($action, $this->ID);
             if ($child) {
                 $response = new SS_HTTPResponse();
                 $params = $request->getVars();
                 if (isset($params['url'])) {
                     unset($params['url']);
                 }
                 $response->redirect(Controller::join_links($child->Link(Controller::join_links($request->param('ID'), $request->param('OtherID'))), $params ? '?' . http_build_query($params) : null), 301);
                 return $response;
             }
         }
     }
     // we found a page with this URLSegment.
     if ($child) {
         $request->shiftAllParams();
         $request->shift();
         $response = ModelAsController::controller_for($child)->handleRequest($request);
     } else {
         // If a specific locale is requested, and it doesn't match the page found by URLSegment,
         // look for a translation and redirect (see #5001). Only happens on the last child in
         // a potentially nested URL chain.
         if ($request->getVar('locale') && $this->dataRecord && $this->dataRecord->Locale != $request->getVar('locale')) {
             $translation = $this->dataRecord->getTranslation($request->getVar('locale'));
             if ($translation) {
                 $response = new SS_HTTPResponse();
                 $response->redirect($translation->Link(), 301);
                 throw new SS_HTTPResponse_Exception($response);
             }
         }
         Director::set_current_page($this->data());
         $response = parent::handleRequest($request);
         Director::set_current_page(null);
     }
     return $response;
 }
 /**
  * Overloaded to avoid "action doesn't exist" errors - all URL parts in
  * this controller are virtual and handled through handleRequest(), not
  * controller methods.
  *
  * @param $request
  * @param $action
  *
  * @return SS_HTTPResponse
  */
 public function handleAction($request, $action)
 {
     // if we submitted a form, let that pass
     if (!$request->isGET()) {
         return parent::handleAction($request, $action);
     }
     $url = $request->getURL();
     //
     // If the current request has an extension attached to it, strip that
     // off and redirect the user to the page without an extension.
     //
     if (DocumentationHelper::get_extension($url)) {
         $this->response = new SS_HTTPResponse();
         $this->response->redirect(DocumentationHelper::trim_extension_off($url) . '/', 301);
         $request->shift();
         $request->shift();
         return $this->response;
     }
     //
     // Strip off the base url
     //
     $base = ltrim(Config::inst()->get('DocumentationViewer', 'link_base'), '/');
     if ($base && strpos($url, $base) !== false) {
         $url = substr(ltrim($url, '/'), strlen($base));
     } else {
     }
     //
     // Handle any permanent redirections that the developer has defined.
     //
     if ($link = DocumentationPermalinks::map($url)) {
         // the first param is a shortcode for a page so redirect the user to
         // the short code.
         $this->response = new SS_HTTPResponse();
         $this->response->redirect($link, 301);
         $request->shift();
         $request->shift();
         return $this->response;
     }
     //
     // Validate the language provided. Language is a required URL parameter.
     // as we use it for generic interfaces and language selection. If
     // language is not set, redirects to 'en'
     //
     $languages = i18n::get_common_languages();
     if (!($lang = $request->param('Lang'))) {
         $lang = $request->param('Action');
         $action = $request->param('ID');
     } else {
         $action = $request->param('Action');
     }
     if (!$lang) {
         return $this->redirect($this->Link('en'));
     } else {
         if (!isset($languages[$lang])) {
             return $this->httpError(404);
         }
     }
     $request->shift(10);
     $allowed = $this->config()->allowed_actions;
     if (in_array($action, $allowed)) {
         //
         // if it's one of the allowed actions such as search or all then the
         // URL must be prefixed with one of the allowed languages.
         //
         return parent::handleAction($request, $action);
     } else {
         //
         // look up the manifest to see find the nearest match against the
         // list of the URL. If the URL exists then set that as the current
         // page to match against.
         // strip off any extensions.
         // if($cleaned !== $url) {
         // 	$redirect = new SS_HTTPResponse();
         // 	return $redirect->redirect($cleaned, 302);
         // }
         if ($record = $this->getManifest()->getPage($url)) {
             $this->record = $record;
             $this->init();
             $type = get_class($this->record);
             $body = $this->renderWith(array("DocumentationViewer_{$type}", "DocumentationViewer"));
             return new SS_HTTPResponse($body, 200);
         } else {
             if ($redirect = $this->getManifest()->getRedirect($url)) {
                 $response = new SS_HTTPResponse();
                 $to = Controller::join_links(Director::baseURL(), $base, $redirect);
                 return $response->redirect($to, 301);
             } else {
                 if (!$url || $url == $lang) {
                     $body = $this->renderWith(array("DocumentationViewer_DocumentationFolder", "DocumentationViewer"));
                     return new SS_HTTPResponse($body, 200);
                 }
             }
         }
     }
     return $this->httpError(404);
 }
 /**
  * Skip any further processing and immediately respond with a redirect to the passed URL.
  *
  * @param string $destURL
  */
 protected static function force_redirect($destURL)
 {
     $response = new SS_HTTPResponse();
     $response->redirect($destURL, 301);
     HTTP::add_cache_headers($response);
     // TODO: Use an exception - ATM we can be called from _config.php, before Director#handleRequest's try block
     $response->output();
     die;
 }
 /**
  * Handles performing a callback to the Salesforce auth server with the
  * provided authorisation code.
  *
  * @param string $code
  * @param string $state
  * @return SS_HTTPResponse
  * @throws SalesforceAuthException On authentication failure.
  */
 public function callback($code, $state)
 {
     $callback = new RestfulService(self::CALLBACK_URL, -1);
     $callback = $callback->request('', 'POST', array('code' => $code, 'grant_type' => 'authorization_code', 'client_id' => $this->getClientID(), 'client_secret' => $this->getClientSecret(), 'redirect_uri' => $this->getRedirectURL()));
     $callback = json_decode($callback->getBody());
     if (!$callback || !$callback->id) {
         throw new SalesforceAuthException('An invalid authorisation response was returned');
     }
     $id = new RestfulService($callback->id, -1);
     $id->setQueryString(array('oauth_token' => $callback->access_token));
     $id = json_decode($id->request()->getBody());
     if (!$id || !$id->email) {
         throw new SalesforceAuthException('An invalid identity response was returned');
     }
     /** @var Member $member */
     $member = Member::get()->filter('Email', $id->email)->first();
     if (!$member) {
         throw new SalesforceAuthException(sprintf('No member was found for the Salesforce email "%s"', $id->email));
     }
     $state = json_decode($state);
     $redirect = isset($state->redirect) ? $state->redirect : null;
     $member->logIn(!empty($state->remember));
     $member->extend('onSalesforceIdentify', $id);
     $response = new SS_HTTPResponse();
     if ($redirect && Director::is_site_url($redirect)) {
         return $response->redirect($redirect);
     }
     if ($redirect = Config::inst()->get('Security', 'default_login_dest')) {
         return $response->redirect($redirect);
     }
     return $response->redirect(Director::absoluteBaseURL());
 }
Exemple #19
0
 /**
  * Process the given URL, creating the appropriate controller and executing it.
  * 
  * Request processing is handled as follows:
  *  - Director::direct() creates a new SS_HTTPResponse object and passes this to Director::handleRequest().
  *  - Director::handleRequest($request) checks each of the Director rules and identifies a controller to handle this 
  *    request.
  *  - Controller::handleRequest($request) is then called.  This will find a rule to handle the URL, and call the rule
  *    handling method.
  *  - RequestHandler::handleRequest($request) is recursively called whenever a rule handling method returns a
  *    RequestHandler object.
  *
  * In addition to request processing, Director will manage the session, and perform the output of the actual response
  * to the browser.
  * 
  * @param $url String, the URL the user is visiting, without the querystring.
  * @uses handleRequest() rule-lookup logic is handled by this.
  * @uses Controller::run() Controller::run() handles the page logic for a Director::direct() call.
  */
 static function direct($url, DataModel $model)
 {
     // Validate $_FILES array before merging it with $_POST
     foreach ($_FILES as $k => $v) {
         if (is_array($v['tmp_name'])) {
             $v = ArrayLib::array_values_recursive($v['tmp_name']);
             foreach ($v as $tmpFile) {
                 if ($tmpFile && !is_uploaded_file($tmpFile)) {
                     user_error("File upload '{$k}' doesn't appear to be a valid upload", E_USER_ERROR);
                 }
             }
         } else {
             if ($v['tmp_name'] && !is_uploaded_file($v['tmp_name'])) {
                 user_error("File upload '{$k}' doesn't appear to be a valid upload", E_USER_ERROR);
             }
         }
     }
     $req = new SS_HTTPRequest(isset($_SERVER['X-HTTP-Method-Override']) ? $_SERVER['X-HTTP-Method-Override'] : $_SERVER['REQUEST_METHOD'], $url, $_GET, ArrayLib::array_merge_recursive((array) $_POST, (array) $_FILES), @file_get_contents('php://input'));
     $headers = self::extract_request_headers($_SERVER);
     foreach ($headers as $header => $value) {
         $req->addHeader($header, $value);
     }
     // Only resume a session if its not started already, and a session identifier exists
     if (!isset($_SESSION) && (isset($_COOKIE[session_name()]) || isset($_REQUEST[session_name()]))) {
         Session::start();
     }
     // Initiate an empty session - doesn't initialize an actual PHP session until saved (see belwo)
     $session = new Session(isset($_SESSION) ? $_SESSION : null);
     $output = Injector::inst()->get('RequestProcessor')->preRequest($req, $session, $model);
     if ($output === false) {
         // @TODO Need to NOT proceed with the request in an elegant manner
         throw new SS_HTTPResponse_Exception(_t('Director.INVALID_REQUEST', 'Invalid request'), 400);
     }
     $result = Director::handleRequest($req, $session, $model);
     // Save session data (and start/resume it if required)
     $session->inst_save();
     // Return code for a redirection request
     if (is_string($result) && substr($result, 0, 9) == 'redirect:') {
         $response = new SS_HTTPResponse();
         $response->redirect(substr($result, 9));
         $res = Injector::inst()->get('RequestProcessor')->postRequest($req, $response, $model);
         if ($res !== false) {
             $response->output();
         }
         // Handle a controller
     } else {
         if ($result) {
             if ($result instanceof SS_HTTPResponse) {
                 $response = $result;
             } else {
                 $response = new SS_HTTPResponse();
                 $response->setBody($result);
             }
             $res = Injector::inst()->get('RequestProcessor')->postRequest($req, $response, $model);
             if ($res !== false) {
                 $response->output();
             } else {
                 // @TODO Proper response here.
                 throw new SS_HTTPResponse_Exception("Invalid response");
             }
             //$controllerObj->getSession()->inst_save();
         }
     }
 }
 /**
  * This acts the same as {@link Controller::handleRequest()}, but if an action cannot be found this will attempt to
  * fall over to a child controller in order to provide functionality for nested URLs.
  *
  * @param SS_HTTPRequest $request
  * @param DataModel $model
  * @return SS_HTTPResponse
  * @throws SS_HTTPResponse_Exception
  */
 public function handleRequest(SS_HTTPRequest $request, DataModel $model = null)
 {
     $child = null;
     $action = $request->param('Action');
     $this->setDataModel($model);
     // If nested URLs are enabled, and there is no action handler for the current request then attempt to pass
     // control to a child controller. This allows for the creation of chains of controllers which correspond to a
     // nested URL.
     if ($action && SiteTree::config()->nested_urls && !$this->hasAction($action)) {
         // See ModelAdController->getNestedController() for similar logic
         if (class_exists('Translatable')) {
             Translatable::disable_locale_filter();
         }
         // look for a page with this URLSegment
         $child = $this->model->SiteTree->filter(array('ParentID' => $this->ID, 'URLSegment' => rawurlencode($action)))->first();
         if (class_exists('Translatable')) {
             Translatable::enable_locale_filter();
         }
     }
     // we found a page with this URLSegment.
     if ($child) {
         $request->shiftAllParams();
         $request->shift();
         $response = ModelAsController::controller_for($child)->handleRequest($request, $model);
     } else {
         // If a specific locale is requested, and it doesn't match the page found by URLSegment,
         // look for a translation and redirect (see #5001). Only happens on the last child in
         // a potentially nested URL chain.
         if (class_exists('Translatable')) {
             if ($request->getVar('locale') && $this->dataRecord && $this->dataRecord->Locale != $request->getVar('locale')) {
                 $translation = $this->dataRecord->getTranslation($request->getVar('locale'));
                 if ($translation) {
                     $response = new SS_HTTPResponse();
                     $response->redirect($translation->Link(), 301);
                     throw new SS_HTTPResponse_Exception($response);
                 }
             }
         }
         Director::set_current_page($this->data());
         try {
             $response = parent::handleRequest($request, $model);
             Director::set_current_page(null);
         } catch (SS_HTTPResponse_Exception $e) {
             $this->popCurrent();
             Director::set_current_page(null);
             throw $e;
         }
     }
     return $response;
 }
 /**
  * @throws SS_HTTPResponse_Exception
  */
 public function onBeforeHTTPError404($request)
 {
     $base = strtolower($request->getURL());
     $getVars = $this->arrayToLowercase($request->getVars());
     unset($getVars['url']);
     // Find all the RedirectedURL objects where the base URL matches.
     // Assumes the base url has no trailing slash.
     $SQL_base = Convert::raw2sql(rtrim($base, '/'));
     $potentials = DataObject::get("RedirectedURL", "\"FromBase\" = '/" . $SQL_base . "'", "\"FromQuerystring\" ASC");
     $listPotentials = new ArrayList();
     foreach ($potentials as $potential) {
         $listPotentials->push($potential);
     }
     // Find any matching FromBase elements terminating in a wildcard /*
     $baseparts = explode('/', $base);
     for ($pos = count($baseparts) - 1; $pos >= 0; $pos--) {
         $basestr = implode('/', array_slice($baseparts, 0, $pos));
         $basepart = Convert::raw2sql($basestr . '/*');
         $basepots = DataObject::get("RedirectedURL", "\"FromBase\" = '/" . $basepart . "'", "\"FromQuerystring\" ASC");
         foreach ($basepots as $basepot) {
             // If the To URL ends in a wildcard /*, append the remaining request URL elements
             if (substr($basepot->To, -2) === '/*') {
                 $basepot->To = substr($basepot->To, 0, -2) . substr($base, strlen($basestr));
             }
             $listPotentials->push($basepot);
         }
     }
     $matched = null;
     // Then check the get vars, ignoring any additional get vars that
     // this URL may have
     if ($listPotentials) {
         foreach ($listPotentials as $potential) {
             $allVarsMatch = true;
             if ($potential->FromQuerystring) {
                 $reqVars = array();
                 parse_str($potential->FromQuerystring, $reqVars);
                 foreach ($reqVars as $k => $v) {
                     if (!$v) {
                         continue;
                     }
                     if (!isset($getVars[$k]) || $v != $getVars[$k]) {
                         $allVarsMatch = false;
                         break;
                     }
                 }
             }
             if ($allVarsMatch) {
                 $matched = $potential;
                 break;
             }
         }
     }
     // If there's a match, direct!
     if ($matched) {
         $response = new SS_HTTPResponse();
         $dest = $matched->To;
         $response->redirect(Director::absoluteURL($dest), 301);
         throw new SS_HTTPResponse_Exception($response);
     }
     // Otherwise check for default MOSS-fixing.
     if (preg_match('/pages\\/default.aspx$/i', $base)) {
         $newBase = preg_replace('/pages\\/default.aspx$/i', '', $base);
         $response = new SS_HTTPResponse();
         $response->redirect(Director::absoluteURL($newBase), 301);
         throw new SS_HTTPResponse_Exception($response);
     }
 }
 /**
  *	Attempt to redirect towards the highest priority link mapping that may have been defined.
  *
  *	@URLparameter direct <{BYPASS_LINK_MAPPINGS}> boolean
  */
 public function postRequest(SS_HTTPRequest $request, SS_HTTPResponse $response, DataModel $model)
 {
     // Bypass the request filter when requesting specific director rules such as "/admin" or "/dev".
     $requestURL = $request->getURL();
     $configuration = Config::inst();
     foreach ($configuration->get('Director', 'rules') as $segment => $controller) {
         // Retrieve the specific director rules.
         if (($position = strpos($segment, '$')) !== false) {
             $segment = rtrim(substr($segment, 0, $position), '/');
         }
         // Determine if the current request matches a specific director rule.
         if ($segment && strpos($requestURL, $segment) === 0) {
             // Continue processing the response.
             return true;
         }
     }
     // Bypass the request filter when using the direct GET parameter.
     if ($request->getVar('direct')) {
         // Continue processing the response.
         return true;
     }
     // Determine the default automated URL handling response status.
     $status = $response->getStatusCode();
     $success = $status >= 200 && $status < 300;
     $error = $status === 404;
     // Either hook into a page not found, or when enforced, replace the default automated URL handling.
     $enforce = $configuration->get('MisdirectionRequestFilter', 'enforce_misdirection');
     $replace = $configuration->get('MisdirectionRequestFilter', 'replace_default');
     if (($error || $enforce || $replace) && ($map = $this->service->getMappingByRequest($request))) {
         // Update the response code where appropriate.
         $responseCode = $map->ResponseCode;
         if ($responseCode == 0) {
             $responseCode = 303;
         } else {
             if ($responseCode == 301 && $map->ForwardPOSTRequest) {
                 $responseCode = 308;
             } else {
                 if ($responseCode == 303 && $map->ForwardPOSTRequest) {
                     $responseCode = 307;
                 }
             }
         }
         // Update the response using the link mapping redirection.
         $response->redirect($map->getLink(), $responseCode);
     } else {
         if ($error && ($fallback = $this->service->determineFallback($requestURL))) {
             // Update the response code where appropriate.
             $responseCode = $fallback['code'];
             if ($responseCode === 0) {
                 $responseCode = 303;
             }
             // Update the response using the fallback, enforcing no further redirection.
             $response->redirect(HTTP::setGetVar('direct', true, Controller::join_links(Director::absoluteBaseURL(), $fallback['link'])), $responseCode);
         } else {
             if (!$error && !$success && $replace) {
                 $response->setStatusCode(404);
                 // Retrieve the appropriate page not found response.
                 ClassInfo::exists('SiteTree') && ($page = ErrorPage::response_for(404)) ? $response->setBody($page->getBody()) : $response->setBody('No URL was matched!');
             }
         }
     }
     // Continue processing the response.
     return true;
 }