From 54938171d76f00228ac81a262ab12cabc582efe9 Mon Sep 17 00:00:00 2001 From: Andrew Paxley Date: Mon, 25 Sep 2023 16:46:40 +1300 Subject: [PATCH] ENH add config for allowed_error_codes --- README.md | 13 +++++++++++ src/ErrorPage.php | 44 ++++++++++++++++++++++++------------ tests/ErrorPageTest.php | 19 ++++++++++++++++ tests/ErrorPageTest.yml | 7 ++++++ tests/Fake/FakeErrorPage.php | 14 ++++++++++++ 5 files changed, 83 insertions(+), 14 deletions(-) create mode 100644 tests/Fake/FakeErrorPage.php diff --git a/README.md b/README.md index c6187ef..826a090 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,19 @@ SilverStripe\ErrorPage\ErrorPage: dev_append_error_message: false ``` +### Limiting optios in the CMS +By default, all available error codes are present in the dropdown in the CMS. This can be overwhelming and there are a few (looking at you, 418) that can +be confusing. To that end, you can limit the codes in the dropdown with the config value `allowed_error_codes` like so: + +```yml +SilverStripe\ErrorPage\ErrorPage: + allowed_error_codes: + - 400 + - 403 + - 404 + - 500 +``` + ## Reporting Issues Please [create an issue](http://github.com/silverstripe/silverstripe-errorpage/issues) for any bugs you've found, or features you're missing. diff --git a/src/ErrorPage.php b/src/ErrorPage.php index 82314e1..75a333f 100644 --- a/src/ErrorPage.php +++ b/src/ErrorPage.php @@ -38,19 +38,19 @@ */ class ErrorPage extends Page { - private static $db = array( + private static $db = [ "ErrorCode" => "Int", - ); + ]; - private static $defaults = array( + private static $defaults = [ "ShowInMenus" => 0, "ShowInSearch" => 0, "ErrorCode" => 400 - ); + ]; private static $table_name = 'ErrorPage'; - private static $allowed_children = array(); + private static $allowed_children = []; private static $description = 'Custom content for different error cases (e.g. "Page not found")'; @@ -80,6 +80,15 @@ class ErrorPage extends Page */ private static $store_filepath = null; + /** + * An array of error codes to allow in the CMS + * If unset, defaults to all available codes (see self::getCodes()) + * + * @config + * @var ?array + */ + private static $allowed_error_codes = null; + /** * @param $member * @@ -106,9 +115,9 @@ public static function response_for($statusCode, $errorMessage = null) // first attempt to dynamically generate the error page /** @var ErrorPage $errorPage */ $errorPage = ErrorPage::get() - ->filter(array( + ->filter([ "ErrorCode" => $statusCode - ))->first(); + ])->first(); if ($errorPage) { Requirements::clear(); @@ -226,8 +235,8 @@ protected function requireDefaultRecordFixture($defaultData) */ protected function getDefaultRecords() { - $data = array( - array( + $data = [ + [ 'ErrorCode' => 404, 'Title' => _t('SilverStripe\\ErrorPage\\ErrorPage.DEFAULTERRORPAGETITLE', 'Page not found'), 'Content' => _t( @@ -235,16 +244,16 @@ protected function getDefaultRecords() '

Sorry, it seems you were trying to access a page that doesn\'t exist.

' . '

Please check the spelling of the URL you were trying to access and try again.

' ) - ), - array( + ], + [ 'ErrorCode' => 500, 'Title' => _t('SilverStripe\\ErrorPage\\ErrorPage.DEFAULTSERVERERRORPAGETITLE', 'Server error'), 'Content' => _t( 'SilverStripe\\ErrorPage\\ErrorPage.DEFAULTSERVERERRORPAGECONTENT', '

Sorry, there was a problem with handling your request.

' ) - ) - ); + ] + ]; $this->extend('getDefaultRecords', $data); @@ -384,7 +393,7 @@ public static function get_content_for_errorcode($statusCode) protected function getCodes() { - return [ + $allCodes = [ 400 => _t('SilverStripe\\ErrorPage\\ErrorPage.CODE_400', '400 - Bad Request'), 401 => _t('SilverStripe\\ErrorPage\\ErrorPage.CODE_401', '401 - Unauthorized'), 402 => _t('SilverStripe\\ErrorPage\\ErrorPage.CODE_402', '402 - Payment Required'), @@ -426,6 +435,13 @@ protected function getCodes() 510 => _t('SilverStripe\\ErrorPage\\ErrorPage.CODE_510', '510 - Not Extended'), 511 => _t('SilverStripe\\ErrorPage\\ErrorPage.CODE_511', '511 - Network Authentication Required'), ]; + + $allowedCodes = self::config()->get('allowed_error_codes'); + if ($allowedCodes === null) { + return $allCodes; + } + + return array_intersect_key($allCodes, array_flip($allowedCodes)); } /** diff --git a/tests/ErrorPageTest.php b/tests/ErrorPageTest.php index 8dfff69..0ef3a7b 100644 --- a/tests/ErrorPageTest.php +++ b/tests/ErrorPageTest.php @@ -14,6 +14,7 @@ use SilverStripe\Core\Config\Config; use SilverStripe\Dev\FunctionalTest; use SilverStripe\ErrorPage\ErrorPage; +use SilverStripe\ErrorPage\Tests\Fake\FakeErrorPage; use SilverStripe\ORM\DB; use SilverStripe\ORM\ValidationException; use SilverStripe\Versioned\Versioned; @@ -40,6 +41,7 @@ protected function setUp(): void // Set temporary asset backend store TestAssetStore::activate('ErrorPageTest'); Config::modify()->set(ErrorPage::class, 'enable_static_file', true); + Config::modify()->set(ErrorPage::class, 'allowed_error_codes', null); $this->logInWithPermission('ADMIN'); } @@ -283,4 +285,21 @@ public function testRequiredRecords() $this->expectOutputRegex('/.*500 error page refreshed.*/'); ErrorPage::singleton()->requireDefaultRecords(); } + + public function testAllowedAllErrorCodes() + { + $page = $this->objFromFixture(FakeErrorPage::class, '418'); + $allCodes = $page->codesForDropdown(); + $this->assertCount(40, $allCodes); + } + + public function testAllowedErrorCodes() + { + Config::modify()->set(ErrorPage::class, 'allowed_error_codes', [400, 500]); + $page = $this->objFromFixture(FakeErrorPage::class, '418'); + $codes = $page->codesForDropdown(); + $this->assertCount(2, $codes); + $this->assertArrayHasKey(400, $codes); + $this->assertArrayHasKey(500, $codes); + } } diff --git a/tests/ErrorPageTest.yml b/tests/ErrorPageTest.yml index d3d0a3c..178d5a2 100644 --- a/tests/ErrorPageTest.yml +++ b/tests/ErrorPageTest.yml @@ -10,6 +10,13 @@ SilverStripe\ErrorPage\ErrorPage: Content: You do not have permission to view this page ErrorCode: 403 +SilverStripe\ErrorPage\Tests\Fake\FakeErrorPage: + 418: + Title: "I'm a teapot" + URLSegment: im-a-teapot + Content: "I'm a teapot" + ErrorCode: 418 + SilverStripe\CMS\Model\SiteTree: home: Title: Home diff --git a/tests/Fake/FakeErrorPage.php b/tests/Fake/FakeErrorPage.php new file mode 100644 index 0000000..be502c8 --- /dev/null +++ b/tests/Fake/FakeErrorPage.php @@ -0,0 +1,14 @@ +getCodes(); + } +} \ No newline at end of file