/** * 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)); }