/** * Render or return a backtrace from the given scope. * * @param mixed $returnVal * @param bool $ignoreAjax * @param array $ignoredFunctions * @return mixed */ public static function backtrace($returnVal = false, $ignoreAjax = false, $ignoredFunctions = null) { $plainText = Director::is_cli() || Director::is_ajax() && !$ignoreAjax; $result = self::get_rendered_backtrace(debug_backtrace(), $plainText, $ignoredFunctions); if ($returnVal) { return $result; } else { echo $result; return null; } }
/** * Create an instance of an appropriate DebugView object. * * @return DebugView */ public static function create_debug_view() { $service = Director::is_cli() || Director::is_ajax() ? 'SilverStripe\\Dev\\CliDebugView' : 'SilverStripe\\Dev\\DebugView'; return Injector::inst()->get($service); }
/** * Register that we've had a permission failure trying to view the given page * * This will redirect to a login page. * If you don't provide a messageSet, a default will be used. * * @param Controller $controller The controller that you were on to cause the permission * failure. * @param string|array $messageSet The message to show to the user. This * can be a string, or a map of different * messages for different contexts. * If you pass an array, you can use the * following keys: * - default: The default message * - alreadyLoggedIn: The message to * show if the user * is already logged * in and lacks the * permission to * access the item. * * The alreadyLoggedIn value can contain a '%s' placeholder that will be replaced with a link * to log in. * @return HTTPResponse */ public static function permissionFailure($controller = null, $messageSet = null) { self::set_ignore_disallowed_actions(true); if (!$controller) { $controller = Controller::curr(); } if (Director::is_ajax()) { $response = $controller ? $controller->getResponse() : new HTTPResponse(); $response->setStatusCode(403); if (!Member::currentUser()) { $response->setBody(_t('ContentController.NOTLOGGEDIN', 'Not logged in')); $response->setStatusDescription(_t('ContentController.NOTLOGGEDIN', 'Not logged in')); // Tell the CMS to allow re-aunthentication if (CMSSecurity::enabled()) { $response->addHeader('X-Reauthenticate', '1'); } } return $response; } // Prepare the messageSet provided if (!$messageSet) { if ($configMessageSet = static::config()->get('default_message_set')) { $messageSet = $configMessageSet; } else { $messageSet = array('default' => _t('Security.NOTEPAGESECURED', "That page is secured. Enter your credentials below and we will send " . "you right along."), 'alreadyLoggedIn' => _t('Security.ALREADYLOGGEDIN', "You don't have access to this page. If you have another account that " . "can access that page, you can log in again below.", "%s will be replaced with a link to log in.")); } } if (!is_array($messageSet)) { $messageSet = array('default' => $messageSet); } $member = Member::currentUser(); // Work out the right message to show if ($member && $member->exists()) { $response = $controller ? $controller->getResponse() : new HTTPResponse(); $response->setStatusCode(403); //If 'alreadyLoggedIn' is not specified in the array, then use the default //which should have been specified in the lines above if (isset($messageSet['alreadyLoggedIn'])) { $message = $messageSet['alreadyLoggedIn']; } else { $message = $messageSet['default']; } // Somewhat hackish way to render a login form with an error message. $me = new Security(); $form = $me->LoginForm(); $form->sessionMessage($message, 'warning'); Session::set('MemberLoginForm.force_message', 1); $loginResponse = $me->login(); if ($loginResponse instanceof HTTPResponse) { return $loginResponse; } $response->setBody((string) $loginResponse); $controller->extend('permissionDenied', $member); return $response; } else { $message = $messageSet['default']; } Session::set("Security.Message.message", $message); Session::set("Security.Message.type", 'warning'); Session::set("BackURL", $_SERVER['REQUEST_URI']); // TODO AccessLogEntry needs an extension to handle permission denied errors // Audit logging hook $controller->extend('permissionDenied', $member); return $controller->redirect(Config::inst()->get('SilverStripe\\Security\\Security', 'login_url') . "?BackURL=" . urlencode($_SERVER['REQUEST_URI'])); }
/** * Return the appropriate error content for the given status code * * @param int $statusCode * @return string Content in an appropriate format for the current request */ public function output($statusCode) { // TODO: Refactor into a content-type option if (Director::is_ajax()) { return $this->getTitle(); } $renderer = Debug::create_debug_view(); $output = $renderer->renderHeader(); $output .= $renderer->renderInfo("Website Error", $this->getTitle(), $this->getBody()); if (Email::config()->admin_email) { $mailto = Email::obfuscate(Email::config()->admin_email); $output .= $renderer->renderParagraph('Contact an administrator: ' . $mailto . ''); } $output .= $renderer->renderFooter(); return $output; }
public function testCoreGlobalVariableCalls() { $this->assertEquals(Director::absoluteBaseURL(), $this->render('{$absoluteBaseURL}'), 'Director::absoluteBaseURL can be called from within template'); $this->assertEquals(Director::absoluteBaseURL(), $this->render('{$AbsoluteBaseURL}'), 'Upper-case %AbsoluteBaseURL can be called from within template'); $this->assertEquals(Director::is_ajax(), $this->render('{$isAjax}'), 'All variations of is_ajax result in the correct call'); $this->assertEquals(Director::is_ajax(), $this->render('{$IsAjax}'), 'All variations of is_ajax result in the correct call'); $this->assertEquals(Director::is_ajax(), $this->render('{$is_ajax}'), 'All variations of is_ajax result in the correct call'); $this->assertEquals(Director::is_ajax(), $this->render('{$Is_ajax}'), 'All variations of is_ajax result in the correct call'); $this->assertEquals(i18n::get_locale(), $this->render('{$i18nLocale}'), 'i18n template functions result correct result'); $this->assertEquals(i18n::get_locale(), $this->render('{$get_locale}'), 'i18n template functions result correct result'); $this->assertEquals((string) Member::currentUser(), $this->render('{$CurrentMember}'), 'Member template functions result correct result'); $this->assertEquals((string) Member::currentUser(), $this->render('{$CurrentUser}'), 'Member template functions result correct result'); $this->assertEquals((string) Member::currentUser(), $this->render('{$currentMember}'), 'Member template functions result correct result'); $this->assertEquals((string) Member::currentUser(), $this->render('{$currentUser}'), 'Member template functions result correct result'); $this->assertEquals(SecurityToken::getSecurityID(), $this->render('{$getSecurityID}'), 'SecurityToken template functions result correct result'); $this->assertEquals(SecurityToken::getSecurityID(), $this->render('{$SecurityID}'), 'SecurityToken template functions result correct result'); $this->assertEquals(Permission::check("ADMIN"), (bool) $this->render('{$HasPerm(\'ADMIN\')}'), 'Permissions template functions result correct result'); $this->assertEquals(Permission::check("ADMIN"), (bool) $this->render('{$hasPerm(\'ADMIN\')}'), 'Permissions template functions result correct result'); }
/** * 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; } } }
/** * Performs the actual action of adding the object to the ChangeSet, once the ChangeSet ID is known * * @param DataObject $object The object to add to the ChangeSet * @param int $campaignID The ID of the ChangeSet to add $object to * @return HTTPResponse * @throws HTTPResponse_Exception */ public function addToCampaign($object, $campaignID) { /** @var ChangeSet $changeSet */ $changeSet = ChangeSet::get()->byID($campaignID); if (!$changeSet) { $this->controller->httpError(404, _t('AddToCampaign.ErrorNotFound', 'That {Type} couldn\'t be found', '', ['Type' => 'Campaign'])); return null; } if (!$changeSet->canEdit()) { $this->controller->httpError(403, _t('AddToCampaign.ErrorCampaignPermissionDenied', 'It seems you don\'t have the necessary permissions to add {ObjectTitle} to {CampaignTitle}', '', ['ObjectTitle' => $object->Title, 'CampaignTitle' => $changeSet->Title])); return null; } $changeSet->addObject($object); $request = $this->controller->getRequest(); $message = _t('AddToCampaign.Success', 'Successfully added {ObjectTitle} to {CampaignTitle}', '', ['ObjectTitle' => $object->Title, 'CampaignTitle' => $changeSet->Title]); if ($request->getHeader('X-Formschema-Request')) { return $message; } elseif (Director::is_ajax()) { $response = new HTTPResponse($message, 200); $response->addHeader('Content-Type', 'text/plain; charset=utf-8'); return $response; } else { return $this->controller->getController()->redirectBack(); } }