/**
  * Turn all relative URLs in the content to absolute URLs.
  *
  * @param string $html
  *
  * @return string
  */
 public static function absoluteURLs($html)
 {
     $html = str_replace('$CurrentPageURL', $_SERVER['REQUEST_URI'], $html);
     return HTTP::urlRewriter($html, function ($url) {
         //no need to rewrite, if uri has a protocol (determined here by existence of reserved URI character ":")
         if (preg_match('/^\\w+:/', $url)) {
             return $url;
         }
         return Director::absoluteURL($url, true);
     });
 }
 /**
  * Get the absolute URL to this resource
  *
  * @return string
  */
 public function getAbsoluteURL()
 {
     if (!$this->exists()) {
         return null;
     }
     return Director::absoluteURL($this->getURL());
 }
 /**
  * Returns the appropriate response up the controller chain
  * if {@link validate()} fails (which is checked prior to executing any form actions).
  * By default, returns different views for ajax/non-ajax request, and
  * handles 'application/json' requests with a JSON object containing the error messages.
  * Behaviour can be influenced by setting {@link $redirectToFormOnValidationError},
  * and can be overruled by setting {@link $validationResponseCallback}.
  *
  * @return HTTPResponse|string
  */
 protected function getValidationErrorResponse()
 {
     $callback = $this->getValidationResponseCallback();
     if ($callback && ($callbackResponse = $callback())) {
         return $callbackResponse;
     }
     $request = $this->getRequest();
     if ($request->isAjax()) {
         // Special case for legacy Validator.js implementation
         // (assumes eval'ed javascript collected through FormResponse)
         $acceptType = $request->getHeader('Accept');
         if (strpos($acceptType, 'application/json') !== FALSE) {
             // Send validation errors back as JSON with a flag at the start
             $response = new HTTPResponse(Convert::array2json($this->validator->getErrors()));
             $response->addHeader('Content-Type', 'application/json');
         } else {
             $this->setupFormErrors();
             // Send the newly rendered form tag as HTML
             $response = new HTTPResponse($this->forTemplate());
             $response->addHeader('Content-Type', 'text/html');
         }
         return $response;
     } else {
         if ($this->getRedirectToFormOnValidationError()) {
             if ($pageURL = $request->getHeader('Referer')) {
                 if (Director::is_site_url($pageURL)) {
                     // Remove existing pragmas
                     $pageURL = preg_replace('/(#.*)/', '', $pageURL);
                     $pageURL = Director::absoluteURL($pageURL, true);
                     return $this->controller->redirect($pageURL . '#' . $this->FormName());
                 }
             }
         }
         return $this->controller->redirectBack();
     }
 }
 /**
  * Gets the url to return to after build
  *
  * @return string|null
  */
 protected function getReturnURL()
 {
     $url = $this->request->getVar('returnURL');
     // Check that this url is a site url
     if (empty($url) || !Director::is_site_url($url)) {
         return null;
     }
     // Convert to absolute URL
     return Director::absoluteURL($url, true);
 }
 /**
  * Change the password
  *
  * @param array $data The user submitted data
  * @return HTTPResponse
  */
 public function doChangePassword(array $data)
 {
     if ($member = Member::currentUser()) {
         // The user was logged in, check the current password
         if (empty($data['OldPassword']) || !$member->checkPassword($data['OldPassword'])->valid()) {
             $this->clearMessage();
             $this->sessionMessage(_t('Member.ERRORPASSWORDNOTMATCH', "Your current password does not match, please try again"), "bad");
             // redirect back to the form, instead of using redirectBack() which could send the user elsewhere.
             return $this->controller->redirect($this->controller->Link('changepassword'));
         }
     }
     if (!$member) {
         if (Session::get('AutoLoginHash')) {
             $member = Member::member_from_autologinhash(Session::get('AutoLoginHash'));
         }
         // The user is not logged in and no valid auto login hash is available
         if (!$member) {
             Session::clear('AutoLoginHash');
             return $this->controller->redirect($this->controller->Link('login'));
         }
     }
     // Check the new password
     if (empty($data['NewPassword1'])) {
         $this->clearMessage();
         $this->sessionMessage(_t('Member.EMPTYNEWPASSWORD', "The new password can't be empty, please try again"), "bad");
         // redirect back to the form, instead of using redirectBack() which could send the user elsewhere.
         return $this->controller->redirect($this->controller->Link('changepassword'));
     } else {
         if ($data['NewPassword1'] == $data['NewPassword2']) {
             $isValid = $member->changePassword($data['NewPassword1']);
             if ($isValid->valid()) {
                 // Clear locked out status
                 $member->LockedOutUntil = null;
                 $member->FailedLoginCount = null;
                 $member->write();
                 if ($member->canLogIn()->valid()) {
                     $member->logIn();
                 }
                 // TODO Add confirmation message to login redirect
                 Session::clear('AutoLoginHash');
                 if (!empty($_REQUEST['BackURL']) && Director::is_site_url($_REQUEST['BackURL'])) {
                     $url = Director::absoluteURL($_REQUEST['BackURL']);
                     return $this->controller->redirect($url);
                 } else {
                     // Redirect to default location - the login form saying "You are logged in as..."
                     $redirectURL = HTTP::setGetVar('BackURL', Director::absoluteBaseURL(), $this->controller->Link('login'));
                     return $this->controller->redirect($redirectURL);
                 }
             } else {
                 $this->clearMessage();
                 $this->sessionMessage(_t('Member.INVALIDNEWPASSWORD', "We couldn't accept that password: {password}", array('password' => nl2br("\n" . Convert::raw2xml($isValid->starredList())))), "bad", false);
                 // redirect back to the form, instead of using redirectBack() which could send the user elsewhere.
                 return $this->controller->redirect($this->controller->Link('changepassword'));
             }
         } else {
             $this->clearMessage();
             $this->sessionMessage(_t('Member.ERRORNEWPASSWORD', "You have entered your new password differently, try again"), "bad");
             // redirect back to the form, instead of using redirectBack() which could send the user elsewhere.
             return $this->controller->redirect($this->controller->Link('changepassword'));
         }
     }
 }
 /**
  * Force a redirect to a domain starting with "www."
  */
 public static function forceWWW()
 {
     if (!Director::isDev() && !Director::isTest() && strpos($_SERVER['HTTP_HOST'], 'www') !== 0) {
         $destURL = str_replace(Director::protocol(), Director::protocol() . 'www.', Director::absoluteURL($_SERVER['REQUEST_URI']));
         self::force_redirect($destURL);
     }
 }
 /**
  * Redirect back. Uses either the HTTP-Referer or a manually set request-variable called "BackURL".
  * This variable is needed in scenarios where HTTP-Referer is not sent (e.g when calling a page by
  * location.href in IE). If none of the two variables is available, it will redirect to the base
  * URL (see {@link Director::baseURL()}).
  *
  * @uses redirect()
  *
  * @return bool|HTTPResponse
  */
 public function redirectBack()
 {
     // Don't cache the redirect back ever
     HTTP::set_cache_age(0);
     $url = null;
     // In edge-cases, this will be called outside of a handleRequest() context; in that case,
     // redirect to the homepage - don't break into the global state at this stage because we'll
     // be calling from a test context or something else where the global state is inappropraite
     if ($this->getRequest()) {
         if ($this->getRequest()->requestVar('BackURL')) {
             $url = $this->getRequest()->requestVar('BackURL');
         } else {
             if ($this->getRequest()->isAjax() && $this->getRequest()->getHeader('X-Backurl')) {
                 $url = $this->getRequest()->getHeader('X-Backurl');
             } else {
                 if ($this->getRequest()->getHeader('Referer')) {
                     $url = $this->getRequest()->getHeader('Referer');
                 }
             }
         }
     }
     if (!$url) {
         $url = Director::baseURL();
     }
     // absolute redirection URLs not located on this site may cause phishing
     if (Director::is_site_url($url)) {
         $url = Director::absoluteURL($url, true);
         return $this->redirect($url);
     } else {
         return false;
     }
 }
 public function updateCMSEditLink(&$link)
 {
     // Update edit link for this file to point to the new asset admin
     $controller = AssetAdmin::singleton();
     $link = Director::absoluteURL($controller->getFileEditLink($this->owner));
 }
        DB::connect($databaseConfig);
    }
    // Check if a token is requesting a redirect
    if (!$reloadToken) {
        return;
    }
    // Otherwise, we start up the session if needed
    if (!isset($_SESSION) && Session::request_contains_session_id()) {
        Session::start();
    }
    // Next, check if we're in dev mode, or the database doesn't have any security data, or we are admin
    if (Director::isDev() || !Security::database_is_ready() || Permission::check('ADMIN')) {
        return $reloadToken->reloadWithToken();
    }
    // Fail and redirect the user to the login page
    $loginPage = Director::absoluteURL(Security::config()->login_url);
    $loginPage .= "?BackURL=" . urlencode($_SERVER['REQUEST_URI']);
    header('location: ' . $loginPage, true, 302);
    die;
})->thenIfErrored(function () use($reloadToken) {
    if ($reloadToken) {
        $reloadToken->reloadWithToken();
    }
})->execute();
global $databaseConfig;
// Redirect to the installer if no database is selected
if (!isset($databaseConfig) || !isset($databaseConfig['database']) || !$databaseConfig['database']) {
    if (!file_exists(BASE_PATH . '/install.php')) {
        header($_SERVER['SERVER_PROTOCOL'] . " 500 Server Error");
        die('SilverStripe Framework requires a $databaseConfig defined.');
    }
 /**
  * Get location of all editor.css files
  *
  * @return array
  */
 protected function getEditorCSS()
 {
     $editor = array();
     // Add standard editor.css
     $editor[] = Director::absoluteURL(FRAMEWORK_ADMIN_DIR . '/client/dist/styles/editor.css');
     // Themed editor.css
     $themedEditor = ThemeResourceLoader::instance()->findThemedCSS('editor', SSViewer::get_themes());
     if ($themedEditor) {
         $editor[] = Director::absoluteURL($themedEditor, Director::BASE);
     }
     return $editor;
 }
    /**
     * Send this HTTPReponse to the browser
     */
    public function output()
    {
        // Attach appropriate X-Include-JavaScript and X-Include-CSS headers
        if (Director::is_ajax()) {
            Requirements::include_in_response($this);
        }
        if (in_array($this->statusCode, self::$redirect_codes) && headers_sent($file, $line)) {
            $url = Director::absoluteURL($this->headers['Location'], true);
            $urlATT = Convert::raw2htmlatt($url);
            $urlJS = Convert::raw2js($url);
            $title = Director::isDev() ? "{$urlATT}... (output started on {$file}, line {$line})" : "{$urlATT}...";
            echo <<<EOT
<p>Redirecting to <a href="{$urlATT}" title="Click this link if your browser does not redirect you">{$title}</a></p>
<meta http-equiv="refresh" content="1; url={$urlATT}" />
<script type="application/javascript">setTimeout(function(){
\twindow.location.href = "{$urlJS}";
}, 50);</script>
EOT;
        } else {
            $line = $file = null;
            if (!headers_sent($file, $line)) {
                header($_SERVER['SERVER_PROTOCOL'] . " {$this->statusCode} " . $this->getStatusDescription());
                foreach ($this->headers as $header => $value) {
                    //etags need to be quoted
                    if (strcasecmp('etag', $header) === 0 && 0 !== strpos($value, '"')) {
                        $value = sprintf('"%s"', $value);
                    }
                    header("{$header}: {$value}", true, $this->statusCode);
                }
            } else {
                // It's critical that these status codes are sent; we need to report a failure if not.
                if ($this->statusCode >= 300) {
                    user_error("Couldn't set response type to {$this->statusCode} because " . "of output on line {$line} of {$file}", E_USER_WARNING);
                }
            }
            // Only show error pages or generic "friendly" errors if the status code signifies
            // an error, and the response doesn't have any body yet that might contain
            // a more specific error description.
            if (Director::isLive() && $this->isError() && !$this->body) {
                $formatter = Injector::inst()->get('FriendlyErrorFormatter');
                echo $formatter->format(array('code' => $this->statusCode));
            } else {
                echo $this->body;
            }
        }
    }
 /**
  * Login in the user and figure out where to redirect the browser.
  *
  * The $data has this format
  * array(
  *   'AuthenticationMethod' => 'MemberAuthenticator',
  *   'Email' => '*****@*****.**',
  *   'Password' => '1nitialPassword',
  *   'BackURL' => 'test/link',
  *   [Optional: 'Remember' => 1 ]
  * )
  *
  * @param array $data
  * @return HTTPResponse
  */
 protected function logInUserAndRedirect($data)
 {
     Session::clear('SessionForms.MemberLoginForm.Email');
     Session::clear('SessionForms.MemberLoginForm.Remember');
     if (Member::currentUser()->isPasswordExpired()) {
         if (isset($_REQUEST['BackURL']) && ($backURL = $_REQUEST['BackURL'])) {
             Session::set('BackURL', $backURL);
         }
         /** @skipUpgrade */
         $cp = ChangePasswordForm::create($this->controller, 'ChangePasswordForm');
         $cp->sessionMessage(_t('Member.PASSWORDEXPIRED', 'Your password has expired. Please choose a new one.'), 'good');
         return $this->controller->redirect('Security/changepassword');
     }
     // Absolute redirection URLs may cause spoofing
     if (!empty($_REQUEST['BackURL'])) {
         $url = $_REQUEST['BackURL'];
         if (Director::is_site_url($url)) {
             $url = Director::absoluteURL($url);
         } else {
             // Spoofing attack, redirect to homepage instead of spoofing url
             $url = Director::absoluteBaseURL();
         }
         return $this->controller->redirect($url);
     }
     // If a default login dest has been set, redirect to that.
     if ($url = Security::config()->default_login_dest) {
         $url = Controller::join_links(Director::absoluteBaseURL(), $url);
         return $this->controller->redirect($url);
     }
     // Redirect the user to the page where they came from
     $member = Member::currentUser();
     if ($member) {
         $firstname = Convert::raw2xml($member->FirstName);
         if (!empty($data['Remember'])) {
             Session::set('SessionForms.MemberLoginForm.Remember', '1');
             $member->logIn(true);
         } else {
             $member->logIn();
         }
         Session::set('Security.Message.message', _t('Member.WELCOMEBACK', "Welcome Back, {firstname}", array('firstname' => $firstname)));
         Session::set("Security.Message.type", "good");
     }
     return Controller::curr()->redirectBack();
 }
 /**
  * Given a successful login, tell the parent frame to close the dialog
  *
  * @return HTTPResponse|DBField
  */
 public function success()
 {
     // Ensure member is properly logged in
     if (!Member::currentUserID()) {
         return $this->redirectToExternalLogin();
     }
     // Get redirect url
     $controller = $this->getResponseController(_t('CMSSecurity.SUCCESS', 'Success'));
     $backURLs = array($this->getRequest()->requestVar('BackURL'), Session::get('BackURL'), Director::absoluteURL(AdminRootController::config()->url_base, true));
     $backURL = null;
     foreach ($backURLs as $backURL) {
         if ($backURL && Director::is_site_url($backURL)) {
             break;
         }
     }
     // Show login
     $controller = $controller->customise(array('Content' => _t('CMSSecurity.SUCCESSCONTENT', '<p>Login success. If you are not automatically redirected ' . '<a target="_top" href="{link}">click here</a></p>', 'Login message displayed in the cms popup once a user has re-authenticated themselves', array('link' => $backURL))));
     return $controller->renderWith($this->getTemplatesFor('success'));
 }
 /**
  * Get a link to this entry
  *
  * @return string Returns the URL of this entry
  * @throws BadMethodCallException
  */
 public function AbsoluteLink()
 {
     if ($this->failover->hasMethod('AbsoluteLink')) {
         return $this->failover->AbsoluteLink();
     } else {
         if ($this->failover->hasMethod('Link')) {
             return Director::absoluteURL($this->failover->Link());
         }
     }
     throw new BadMethodCallException($this->failover->class . " object has neither an AbsoluteLink nor a Link method." . " Can't put a link in the RSS feed", E_USER_WARNING);
 }
 /**
  * Get the URL of this feed
  *
  * @param string $action
  * @return string Returns the URL of the feed.
  */
 public function Link($action = null)
 {
     return Controller::join_links(Director::absoluteURL($this->link), $action);
 }
 public function testAlternativeBaseURL()
 {
     // Get original protocol and hostname
     $rootURL = Director::protocolAndHost();
     // relative base URLs - you should end them in a /
     Config::inst()->update('SilverStripe\\Control\\Director', 'alternate_base_url', '/relativebase/');
     $_SERVER['REQUEST_URI'] = "{$rootURL}/relativebase/sub-page/";
     $this->assertEquals('/relativebase/', Director::baseURL());
     $this->assertEquals($rootURL . '/relativebase/', Director::absoluteBaseURL());
     $this->assertEquals($rootURL . '/relativebase/subfolder/test', Director::absoluteURL('subfolder/test'));
     // absolute base URLs - you should end them in a /
     Config::inst()->update('SilverStripe\\Control\\Director', 'alternate_base_url', 'http://www.example.org/');
     $_SERVER['REQUEST_URI'] = "http://www.example.org/sub-page/";
     $this->assertEquals('http://www.example.org/', Director::baseURL());
     $this->assertEquals('http://www.example.org/', Director::absoluteBaseURL());
     $this->assertEquals('http://www.example.org/sub-page/', Director::absoluteURL('', Director::REQUEST));
     $this->assertEquals('http://www.example.org/', Director::absoluteURL('', Director::BASE));
     $this->assertEquals('http://www.example.org/', Director::absoluteURL('', Director::ROOT));
     $this->assertEquals('http://www.example.org/sub-page/subfolder/test', Director::absoluteURL('subfolder/test', Director::REQUEST));
     $this->assertEquals('http://www.example.org/subfolder/test', Director::absoluteURL('subfolder/test', Director::ROOT));
     $this->assertEquals('http://www.example.org/subfolder/test', Director::absoluteURL('subfolder/test', Director::BASE));
 }