Module version(s) affected
3.2 that runs with PHP 8.5.0–8.5.3
Description
After clicking "Add" to create a new page in the CMS, the page is created and a toast notification appears, but the browser does not redirect to the new page's edit form. This is caused by a PHP bug, not a Silverstripe code issue.
php/php-src#21018
PHP 8.5.0–8.5.3 introduced a regression in the header() function where replace=true (the default) uses prefix matching instead of exact header name matching. In LeftAndMain::handleRequest(), X-Controller is set after X-ControllerURL has already been added to the response (by AdminController::redirect()). Because X-Controller is a prefix of X-ControllerURL, PHP's buggy header() silently replaces the longer header with the shorter one.
The browser's ajaxComplete handler in LeftAndMain.js reads X-ControllerURL to trigger router.show(url) — but the header is missing, so no redirect happens.
How to reproduce
Requires PHP 8.5.0–8.5.3:
- Open
/admin/pages
- Click "Add" to create a new page
- Fill in the form and submit
- Page is created (toast notification appears) but no redirect to the edit form
Possible Solution
Resolution
Upgrade to PHP 8.5.4+ which fixes the prefix matching bug.
This can be closed as "not a bug" / "external dependency" once PHP 8.5.4 is widely available. Keeping open for now as a reference for anyone hitting this on PHP 8.5.0–8.5.3.
Additional Context
Hackfix (for PHP < 8.5.4)
In vendor/silverstripe/admin/code/LeftAndMain.php, re-add X-ControllerURL after X-Controller:
if (!$response->getHeader('X-Controller')) {
$controllerURL = $response->getHeader('X-ControllerURL');
$response->addHeader('X-Controller', static::class);
if ($controllerURL) {
$response->removeHeader('X-ControllerURL');
$response->addHeader('X-ControllerURL', $controllerURL);
}
}
Validations
Module version(s) affected
3.2 that runs with PHP 8.5.0–8.5.3
Description
After clicking "Add" to create a new page in the CMS, the page is created and a toast notification appears, but the browser does not redirect to the new page's edit form. This is caused by a PHP bug, not a Silverstripe code issue.
php/php-src#21018
PHP 8.5.0–8.5.3 introduced a regression in the
header()function wherereplace=true(the default) uses prefix matching instead of exact header name matching. InLeftAndMain::handleRequest(),X-Controlleris set afterX-ControllerURLhas already been added to the response (byAdminController::redirect()). BecauseX-Controlleris a prefix ofX-ControllerURL, PHP's buggyheader()silently replaces the longer header with the shorter one.The browser's
ajaxCompletehandler inLeftAndMain.jsreadsX-ControllerURLto triggerrouter.show(url)— but the header is missing, so no redirect happens.How to reproduce
Requires PHP 8.5.0–8.5.3:
/admin/pagesPossible Solution
Resolution
Upgrade to PHP 8.5.4+ which fixes the prefix matching bug.
This can be closed as "not a bug" / "external dependency" once PHP 8.5.4 is widely available. Keeping open for now as a reference for anyone hitting this on PHP 8.5.0–8.5.3.
Additional Context
Hackfix (for PHP < 8.5.4)
In
vendor/silverstripe/admin/code/LeftAndMain.php, re-addX-ControllerURLafterX-Controller:Validations
silverstripe/installer(with any code examples you've provided)