public function output() { // TODO: Refactor into a content-type option if (\Director::is_ajax()) { return $this->friendlyErrorMessage; } else { // TODO: Refactor this into CMS if (class_exists('ErrorPage')) { $errorFilePath = \ErrorPage::get_filepath_for_errorcode($this->statusCode, class_exists('Translatable') ? \Translatable::get_current_locale() : null); if (file_exists($errorFilePath)) { $content = file_get_contents($errorFilePath); if (!headers_sent()) { header('Content-Type: text/html'); } // $BaseURL is left dynamic in error-###.html, so that multi-domain sites don't get broken return str_replace('$BaseURL', \Director::absoluteBaseURL(), $content); } } $renderer = \Debug::create_debug_view(); $output = $renderer->renderHeader(); $output .= $renderer->renderInfo("Website Error", $this->friendlyErrorMessage, $this->friendlyErrorDetail); 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 static function create_default_error_page($code = 404, $values = [], $type = 'ErrorPage') { if (class_exists('ErrorPage')) { return; } $pagePath = \ErrorPage::get_filepath_for_errorcode($code); if (!DataList::create('ErrorPage')->filter('ErrorCode', $code)->exists() || !file_exists($pagePath)) { $page = Object::create($type); foreach ($values as $f => $v) { $page->{$f} = $v; } $page->ErrorCode = $code; $page->write(); $page->publish('Stage', 'Live'); $response = static::test(static::makeRelative($page->Link())); $written = null; if ($fh = fopen($pagePath, 'w')) { $written = fwrite($fh, $response->getBody()); fclose($fh); } if ($written) { DB::alteration_message($page->Title . ' Page created', 'created'); } else { DB::alteration_message(sprintf($page->Title . ' Page could not be created at %s. Please check permissions', $pagePath), 'error'); } } }
/** * Create an {@link ErrorPage} for status code 503 * * @see UnderConstruction_Extension::onBeforeInit() * @see DataObjectDecorator::requireDefaultRecords() * @return Void */ function requireDefaultRecords() { // Ensure that an assets path exists before we do any error page creation if (!file_exists(ASSETS_PATH)) { mkdir(ASSETS_PATH); } $pageUnderConstructionErrorPage = DataObject::get_one('ErrorPage', "\"ErrorCode\" = '503'"); $pageUnderConstructionErrorPageExists = $pageUnderConstructionErrorPage && $pageUnderConstructionErrorPage->exists() ? true : false; $pageUnderConstructionErrorPagePath = ErrorPage::get_filepath_for_errorcode(503); if (!($pageUnderConstructionErrorPageExists && file_exists($pageUnderConstructionErrorPagePath))) { if (!$pageUnderConstructionErrorPageExists) { $pageUnderConstructionErrorPage = new ErrorPage(); $pageUnderConstructionErrorPage->ErrorCode = 503; $pageUnderConstructionErrorPage->Title = _t('UnderConstruction.TITLE', 'Under Construction'); $pageUnderConstructionErrorPage->Content = _t('UnderConstruction.CONTENT', '<p>Sorry, this site is currently under construction.</p>'); $pageUnderConstructionErrorPage->Status = 'New page'; $pageUnderConstructionErrorPage->write(); $pageUnderConstructionErrorPage->publish('Stage', 'Live'); } // Ensure a static error page is created from latest error page content $response = Director::test(Director::makeRelative($pageUnderConstructionErrorPage->Link())); if ($fh = fopen($pageUnderConstructionErrorPagePath, 'w')) { $written = fwrite($fh, $response->getBody()); fclose($fh); } if ($written) { DB::alteration_message('503 error page created', 'created'); } else { DB::alteration_message(sprintf('503 error page could not be created at %s. Please check permissions', $pageUnderConstructionErrorPagePath), 'error'); } } }
function testErrorPageLocations() { $subsite1 = $this->objFromFixture('Subsite', 'domaintest1'); Subsite::changeSubsite($subsite1->ID); $path = ErrorPage::get_filepath_for_errorcode(500); $static_path = Config::inst()->get('ErrorPage', 'static_filepath'); $expected_path = $static_path . '/error-500-' . $subsite1->domain() . '.html'; $this->assertEquals($expected_path, $path); }
/** * Display an error page on invalid request. * * @parameter <{ERROR_CODE}> integer * @parameter <{ERROR_MESSAGE}> string */ public function httpError($code, $message = null) { // Determine the error page for the given status code. $errorPages = ClassInfo::exists('SiteTree') ? ErrorPage::get()->filter('ErrorCode', $code) : null; // Allow extension customisation. $this->extend('updateErrorPages', $errorPages); // Retrieve the error page response. if ($errorPages && ($errorPage = $errorPages->first())) { Requirements::clear(); Requirements::clear_combined_files(); $response = ModelAsController::controller_for($errorPage)->handleRequest(new SS_HTTPRequest('GET', ''), DataModel::inst()); throw new SS_HTTPResponse_Exception($response, $code); } else { if ($errorPages && file_exists($cachedPage = ErrorPage::get_filepath_for_errorcode($code, class_exists('Translatable') ? Translatable::get_current_locale() : null))) { $response = new SS_HTTPResponse(); $response->setStatusCode($code); $response->setBody(file_get_contents($cachedPage)); throw new SS_HTTPResponse_Exception($response, $code); } else { return parent::httpError($code, $message); } } }
function requireDefaultRecords() { parent::requireDefaultRecords(); // create a 400 ErrorPage if ($this->class == 'ErrorPage') { // Ensure that an assets path exists before we do any error page creation if (!file_exists(ASSETS_PATH)) { mkdir(ASSETS_PATH); } $ErrorPage400 = DataObject::get_one('ErrorPage', "\"ErrorCode\" = '400'"); $ErrorPage400Exists = $ErrorPage400 && $ErrorPage400->exists() ? true : false; $ErrorPage400Path = ErrorPage::get_filepath_for_errorcode(400); if (!($ErrorPage400Exists && file_exists($ErrorPage400Path))) { if (!$ErrorPage400Exists) { $ErrorPage400 = new ErrorPage(); $ErrorPage400->ErrorCode = 400; $ErrorPage400->Title = _t('ErrorPage.ERRORPAGE400TITLE', '400 Error'); $ErrorPage400->Content = _t('ErrorPage.ERRORPAGE400CONTENT', '<p>An error occurred while processing your request.</p>'); $ErrorPage400->Status = 'New page'; $ErrorPage400->write(); $ErrorPage400->publish('Stage', 'Live'); } // Ensure a static error page is created from latest error page content $response = Director::test(Director::makeRelative($ErrorPage400->Link())); if ($fh = fopen($ErrorPage400Path, 'w')) { $written = fwrite($fh, $response->getBody()); fclose($fh); } if ($written) { DB::alteration_message('400 error page created', 'created'); } else { DB::alteration_message(sprintf('400 error page could not be created at %s. Please check permissions', $ErrorPage400Path), 'error'); } } $ErrorPage412 = DataObject::get_one('ErrorPage', "\"ErrorCode\" = '412'"); $ErrorPage412Exists = $ErrorPage412 && $ErrorPage412->exists() ? true : false; $ErrorPage412Path = ErrorPage::get_filepath_for_errorcode(412); if (!($ErrorPage412Exists && file_exists($ErrorPage412Path))) { if (!$ErrorPage412Exists) { $ErrorPage412 = new ErrorPage(); $ErrorPage412->ErrorCode = 412; $ErrorPage412->Title = _t('ErrorPage.ERRORPAGE412TITLE', '412 Error'); $ErrorPage412->Content = _t('ErrorPage.ERRORPAGE412CONTENT', '<p>Your Session has expired!.</p>'); $ErrorPage412->Status = 'New page'; $ErrorPage412->write(); $ErrorPage412->publish('Stage', 'Live'); } // Ensure a static error page is created from latest error page content $response = Director::test(Director::makeRelative($ErrorPage412->Link())); if ($fh = fopen($ErrorPage412Path, 'w')) { $written = fwrite($fh, $response->getBody()); fclose($fh); } if ($written) { DB::alteration_message('412 error page created', 'created'); } else { DB::alteration_message(sprintf('412 error page could not be created at %s. Please check permissions', $ErrorPage412Path), 'error'); } } } }
/** * Render a user-facing error page, using the default HTML error template * rendered by {@link ErrorPage} if it exists. Doesn't use the standard {@link SS_HTTPResponse} class * the keep dependencies minimal. * * @uses ErrorPage * * @param int $statusCode HTTP Status Code (Default: 500) * @param string $friendlyErrorMessage User-focused error message. Should not contain code pointers * or "tech-speak". Used in the HTTP Header and ajax responses. * @param string $friendlyErrorDetail Detailed user-focused message. Is just used if no {@link ErrorPage} is found * for this specific status code. * @return string HTML error message for non-ajax requests, plaintext for ajax-request. */ public static function friendlyError($statusCode = 500, $friendlyErrorMessage = null, $friendlyErrorDetail = null) { if (!$friendlyErrorMessage) { $friendlyErrorMessage = Config::inst()->get('Debug', 'friendly_error_header'); } if (!$friendlyErrorDetail) { $friendlyErrorDetail = Config::inst()->get('Debug', 'friendly_error_detail'); } if (!headers_sent()) { $currController = Controller::has_curr() ? Controller::curr() : null; // Ensure the error message complies with the HTTP 1.1 spec $msg = strip_tags(str_replace(array("\n", "\r"), '', $friendlyErrorMessage)); if ($currController) { $response = $currController->getResponse(); $response->setStatusCode($statusCode, $msg); } else { header($_SERVER['SERVER_PROTOCOL'] . " {$statusCode} {$msg}"); } } if (Director::is_ajax()) { echo $friendlyErrorMessage; } else { if (class_exists('ErrorPage')) { $errorFilePath = ErrorPage::get_filepath_for_errorcode($statusCode, class_exists('Translatable') ? Translatable::get_current_locale() : null); if (file_exists($errorFilePath)) { $content = file_get_contents(ASSETS_PATH . "/error-{$statusCode}.html"); // $BaseURL is left dynamic in error-###.html, so that multi-domain sites don't get broken echo str_replace('$BaseURL', Director::absoluteBaseURL(), $content); } } else { $renderer = new DebugView(); $renderer->writeHeader(); $renderer->writeInfo("Website Error", $friendlyErrorMessage, $friendlyErrorDetail); if (Email::config()->admin_email) { $mailto = Email::obfuscate(Email::config()->admin_email); $renderer->writeParagraph('Contact an administrator: ' . $mailto . ''); } $renderer->writeFooter(); } } return false; }
/** * Render a user-facing error page, using the default HTML error template * rendered by {@link ErrorPage} if it exists. Doesn't use the standard {@link SS_HTTPResponse} class * the keep dependencies minimal. * * @uses ErrorPage * * @param int $statusCode HTTP Status Code (Default: 500) * @param string $friendlyErrorMessage User-focused error message. Should not contain code pointers or "tech-speak". * Used in the HTTP Header and ajax responses. * @param string $friendlyErrorDetail Detailed user-focused message. Is just used if no {@link ErrorPage} is found * for this specific status code. * @return string HTML error message for non-ajax requests, plaintext for ajax-request. */ static function friendlyError($statusCode = 500, $friendlyErrorMessage = null, $friendlyErrorDetail = null) { if (!$friendlyErrorMessage) { $friendlyErrorMessage = self::$friendly_error_header; } if (!$friendlyErrorDetail) { $friendlyErrorDetail = self::$friendly_error_detail; } if (!headers_sent()) { header(sprintf('%s %d %s', $_SERVER['SERVER_PROTOCOL'], $statusCode, strip_tags(str_replace(array("\n", "\r"), '', $friendlyErrorMessage)))); } if (Director::is_ajax()) { echo $friendlyErrorMessage; } else { $errorFilePath = ErrorPage::get_filepath_for_errorcode($statusCode, Translatable::get_current_locale()); if (file_exists($errorFilePath)) { $content = file_get_contents(ASSETS_PATH . "/error-{$statusCode}.html"); // $BaseURL is left dynamic in error-###.html, so that multi-domain sites don't get broken echo str_replace('$BaseURL', Director::absoluteBaseURL(), $content); } else { $renderer = new DebugView(); $renderer->writeHeader(); $renderer->writeInfo("Website Error", $friendlyErrorMessage, $friendlyErrorDetail); if (Email::getAdminEmail()) { $mailto = Email::obfuscate(Email::getAdminEmail()); $renderer->writeParagraph('Contact an administrator: ' . $mailto . ''); } $renderer->writeFooter(); } } }
/** * Render a user-facing error page, using the default HTML error template * rendered by {@link ErrorPage} if it exists. Doesn't use the standard {@link HTTPResponse} class * the keep dependencies minimal. * * @uses ErrorPage * * @param int $statusCode HTTP Status Code (Default: 500) * @param string $friendlyErrorMessage User-focused error message. Should not contain code pointers or "tech-speak". * Used in the HTTP Header and ajax responses. * @param string $friendlyErrorDetail Detailed user-focused message. Is just used if no {@link ErrorPage} is found * for this specific status code. * @return string HTML error message for non-ajax requests, plaintext for ajax-request. */ static function friendlyError($statusCode = 500, $friendlyErrorMessage = null, $friendlyErrorDetail = null) { if (!$friendlyErrorMessage) { $friendlyErrorMessage = 'There has been an error'; } if (!$friendlyErrorDetail) { $friendlyErrorDetail = 'The website server has not been able to respond to your request.'; } if (!headers_sent()) { header($_SERVER['SERVER_PROTOCOL'] . " {$statusCode} {$friendlyErrorMessage}"); } if (Director::is_ajax()) { echo $friendlyErrorMessage; } else { $errorFilePath = ErrorPage::get_filepath_for_errorcode($statusCode, Translatable::get_current_locale()); if (file_exists($errorFilePath)) { echo file_get_contents($errorFilePath); } else { $renderer = new DebugView(); $renderer->writeHeader(); $renderer->writeInfo("Website Error", $friendlyErrorMessage, $friendlyErrorDetail); if (Email::getAdminEmail()) { $mailto = Email::obfuscate(Email::getAdminEmail()); $renderer->writeParagraph('Contact an administrator: ' . $mailto . ''); } $renderer->writeFooter(); } } }
/** * Render a user-facing error page, using the default HTML error template * rendered by {@link ErrorPage} if it exists. Doesn't use the standard {@link SS_HTTPResponse} class * the keep dependencies minimal. * * @uses ErrorPage * * @param int $statusCode HTTP Status Code (Default: 500) * @param string $friendlyErrorMessage User-focused error message. Should not contain code pointers * or "tech-speak". Used in the HTTP Header and ajax responses. * @param string $friendlyErrorDetail Detailed user-focused message. Is just used if no {@link ErrorPage} is found * for this specific status code. * @return string HTML error message for non-ajax requests, plaintext for ajax-request. */ public static function friendlyError($statusCode = 500, $friendlyErrorMessage = null, $friendlyErrorDetail = null) { // Ensure the error message complies with the HTTP 1.1 spec if (!$friendlyErrorMessage) { $friendlyErrorMessage = Config::inst()->get('Debug', 'friendly_error_header'); } $friendlyErrorMessage = strip_tags(str_replace(array("\n", "\r"), '', $friendlyErrorMessage)); if (!$friendlyErrorDetail) { $friendlyErrorDetail = Config::inst()->get('Debug', 'friendly_error_detail'); } if (!headers_sent()) { // Allow toggle between legacy behaviour and correctly setting HTTP response code // In 4.0 this should be fixed to always set this response code. if (Config::inst()->get('Debug', 'friendly_error_httpcode') || !Controller::has_curr()) { header($_SERVER['SERVER_PROTOCOL'] . " {$statusCode} {$friendlyErrorMessage}"); } } if (Director::is_ajax()) { echo $friendlyErrorMessage; } else { if (!headers_sent()) { header('Content-Type: text/html'); } if (class_exists('ErrorPage')) { $errorFilePath = ErrorPage::get_filepath_for_errorcode($statusCode, class_exists('Translatable') ? Translatable::get_current_locale() : null); if (file_exists($errorFilePath)) { $content = file_get_contents($errorFilePath); // $BaseURL is left dynamic in error-###.html, so that multi-domain sites don't get broken echo str_replace('$BaseURL', Director::absoluteBaseURL(), $content); } } else { $renderer = new DebugView(); $renderer->writeHeader(); $renderer->writeInfo("Website Error", $friendlyErrorMessage, $friendlyErrorDetail); if (Email::config()->admin_email) { $mailto = Email::obfuscate(Email::config()->admin_email); $renderer->writeParagraph('Contact an administrator: ' . $mailto . ''); } $renderer->writeFooter(); } } return false; }