1 <?php
2 3 4 5 6 7 8 9 10 11 12 13
14 class ErrorPage extends Page {
15
16 static $allowed_children = "none";
17
18 static $db = array(
19 "ErrorCode" => "Int",
20 );
21
22 static $defaults = array(
23 "ShowInMenus" => 0,
24 "ShowInSearch" => 0,
25 "ShowInSiteMap" => 0,
26 );
27
28 protected static $static_filepath = ASSETS_PATH;
29
30 31 32 33 34 35
36 public static function response_for($statusCode) {
37
38 if($errorPage = DataObject::get_one('ErrorPage', "\"ErrorCode\" = $statusCode")) {
39 return ModelAsController::controller_for($errorPage)->handleRequest(new SS_HTTPRequest('GET', ''));
40 }
41
42
43 $cachedPath = self::get_filepath_for_errorcode($statusCode, i18n::get_locale());
44
45 if(file_exists($cachedPath)) {
46 $response = new SS_HTTPResponse();
47
48 $response->setStatusCode($statusCode);
49 $response->setBody(file_get_contents($cachedPath));
50
51 return $response;
52 }
53 }
54
55 56 57 58 59 60
61 function requireDefaultRecords() {
62 parent::requireDefaultRecords();
63
64 $errorPage = DataObject::get_one('ErrorPage', "\"ErrorCode\" = '404'");
65 if(!($errorPage && $errorPage->exists())) {
66 $errorpage = new ErrorPage();
67 $errorpage->ErrorCode = 404;
68 $errorpage->Title = _t('ErrorPage.DEFAULTERRORPAGETITLE', 'Page not found');
69 $errorpage->Content = _t('ErrorPage.DEFAULTERRORPAGECONTENT', '<p>Sorry, it seems you were trying to access a page that doesn\'t exist.</p><p>Please check the spelling of the URL you were trying to access and try again.</p>');
70 $errorpage->Status = 'New page';
71 $errorpage->DevEditType = 'Fixed';
72 $errorpage->Sort = -1;
73 $errorpage->write();
74 $errorpage->publish('Stage', 'Live');
75
76 DB::alteration_message('404 page created', 'created');
77 }
78 }
79
80 function onBeforeWrite() {
81 if ($this->ErrorCode && (
82 !$this->URLSegment
83 || substr($this->URLSegment, 0, 4) == 'new-'
84 || preg_match('/^error\d+$/', $this->URLSegment)
85 || $this->URLSegment == $this->generateURLSegment($this->Title)
86 )) {
87 $this->URLSegment = 'error'. $this->ErrorCode;
88 }
89 parent::onBeforeWrite();
90 }
91
92
93 function getCMSFields() {
94 $fields = parent::getCMSFields();
95
96 $fields->addFieldToTab(
97 "Root.Content.Main",
98 new DropdownField(
99 "ErrorCode",
100 $this->fieldLabel('ErrorCode'),
101 array(
102 400 => _t('ErrorPage.400', '400 - Bad Request'),
103 401 => _t('ErrorPage.401', '401 - Unauthorized'),
104 403 => _t('ErrorPage.403', '403 - Forbidden'),
105 404 => _t('ErrorPage.404', '404 - Not Found'),
106 405 => _t('ErrorPage.405', '405 - Method Not Allowed'),
107 406 => _t('ErrorPage.406', '406 - Not Acceptable'),
108 407 => _t('ErrorPage.407', '407 - Proxy Authentication Required'),
109 408 => _t('ErrorPage.408', '408 - Request Timeout'),
110 409 => _t('ErrorPage.409', '409 - Conflict'),
111 410 => _t('ErrorPage.410', '410 - Gone'),
112 411 => _t('ErrorPage.411', '411 - Length Required'),
113 412 => _t('ErrorPage.412', '412 - Precondition Failed'),
114 413 => _t('ErrorPage.413', '413 - Request Entity Too Large'),
115 414 => _t('ErrorPage.414', '414 - Request-URI Too Long'),
116 415 => _t('ErrorPage.415', '415 - Unsupported Media Type'),
117 416 => _t('ErrorPage.416', '416 - Request Range Not Satisfiable'),
118 417 => _t('ErrorPage.417', '417 - Expectation Failed'),
119 500 => _t('ErrorPage.500', '500 - Internal Server Error'),
120 501 => _t('ErrorPage.501', '501 - Not Implemented'),
121 502 => _t('ErrorPage.502', '502 - Bad Gateway'),
122 503 => _t('ErrorPage.503', '503 - Service Unavailable'),
123 504 => _t('ErrorPage.504', '504 - Gateway Timeout'),
124 505 => _t('ErrorPage.505', '505 - HTTP Version Not Supported'),
125 )
126 ),
127 "Content"
128 );
129
130 return $fields;
131 }
132
133 134 135 136 137 138 139 140
141 function doPublish() {
142 parent::doPublish();
143
144
145 $response = Director::test(Director::makeRelative($this->Link()));
146
147 $errorContent = $response->getBody();
148
149 $errorContent = preg_replace('/<base[^>]+href="' . str_replace('/','\\/', Director::absoluteBaseURL()) . '"[^>]*>/i', '<base href="$BaseURL" />', $errorContent);
150
151
152 if(!file_exists(ASSETS_PATH)) {
153 mkdir(ASSETS_PATH, 02775);
154 }
155
156
157
158
159 $filePath = self::get_filepath_for_errorcode($this->ErrorCode, $this->Locale);
160 if($fh = fopen($filePath, "w")) {
161 fwrite($fh, $errorContent);
162 fclose($fh);
163 } else {
164 $fileErrorText = sprintf(
165 _t(
166 "ErrorPage.ERRORFILEPROBLEM",
167 "Error opening file \"%s\" for writing. Please check file permissions."
168 ),
169 $errorFile
170 );
171 FormResponse::status_message($fileErrorText, 'bad');
172 FormResponse::respond();
173 return;
174 }
175 }
176
177 178 179 180 181
182 function fieldLabels($includerelations = true) {
183 $labels = parent::fieldLabels($includerelations);
184 $labels['ErrorCode'] = _t('ErrorPage.CODE', "Error code");
185
186 return $labels;
187 }
188
189 190 191 192 193 194 195 196
197 static function get_filepath_for_errorcode($statusCode, $locale = null) {
198 if (singleton('ErrorPage')->hasMethod('alternateFilepathForErrorcode')) {
199 return singleton('ErrorPage')-> alternateFilepathForErrorcode($statusCode, $locale);
200 }
201 if(singleton('SiteTree')->hasExtension('Translatable') && $locale && $locale != Translatable::default_locale()) {
202 return self::$static_filepath . "/error-{$statusCode}-{$locale}.html";
203 } else {
204 return self::$static_filepath . "/error-{$statusCode}.html";
205 }
206 }
207
208 209 210 211 212 213
214 static function set_static_filepath($path) {
215 self::$static_filepath = $path;
216 }
217
218 219 220
221 static function get_static_filepath() {
222 return self::$static_filepath;
223 }
224 }
225
226 227 228 229
230 class ErrorPage_Controller extends Page_Controller {
231 function init() {
232 parent::init();
233
234 $action = $this->request->param('Action');
235 if(!$action || $action == 'index') {
236 Director::set_status_code($this->failover->ErrorCode ? $this->failover->ErrorCode : 404);
237 }
238
239 }
240 }
241
242
243 ?>
244
[Raise a SilverStripe Framework issue/bug](https://github.com/silverstripe/silverstripe-framework/issues/new)
- [Raise a SilverStripe CMS issue/bug](https://github.com/silverstripe/silverstripe-cms/issues/new)
- Please use the
Silverstripe Forums to ask development related questions.
-