英文:
How to replace deprecated HttpUtility::redirect() with PSR-7 response in legacy TYPO3 plugin?
问题
I have a legacy extension with a plugin that's handled in MyPluginController, which extends TYPO3\CMS\Frontend\Plugin.AbstractPlugin
.
The plugin is registered as a USER_INT
content object:
plugin.tx_myext_pi1.userFunc = Foo\MyExt\Controller\MyPluginController->main
The render() method of both the UserContentObject
and UserInternalContentObject
(which handle USER + USER_INT) return a string (i.e. the rendered output of your plugin).
There are a few instances in my controller, where a redirect is required (e.g. to call the payment page of a remote payment gateway). So far this was done with HttpUtility::redirect()
, but this method has been marked as deprecated as of V11.3 [1].
The deprecation note says that a PSR-7 compliant response object should be used instead. The suggested migration strategies are to either return a Response object directly or throw a PropagateResponseException
. But the latter is considered an "intermediate solution only".
If I return a PSR-7 Response directly, it (predictably) results in an exception as we already know that a string is expected:
Object of class TYPO3\CMS\Core\Http.RedirectResponse could not be converted to string
So what can you do? Is there a sustainable way to issue an HTTP redirect in this scenario? And if not, what else can you do? One could return a dummy page and work with an onload Javascript redirect or try a redirect meta header in HTML. But these are all pretty ugly approaches IMHO.
英文:
I have a legacy extension with a plugin that's handled in MyPluginController, which extends TYPO3\CMS\Frontend\Plugin\AbstractPlugin
.
The plugin is registered as a USER_INT
content object:
plugin.tx_myext_pi1 = USER_INT
plugin.tx_myext_pi1.userFunc = Foo\MyExt\Controller\MyPluginController->main
The render() method of both the UserContentObject
and UserInternalContentObject
(which handle USER + USER_INT) return a string (i.e. the rendered output of your plugin).
There are a few instances in my controller, where a redirect is required (e.g. to call the payment page of a remote payment gateway). So far this was done with HttpUtility::redirect()
, but this method has been marked as deprecated as of V11.3 [1].
The deprecation note says that a PSR-7 compliant response object should be used instead.
The suggested migration strategies are to either return a Response object directly or throw a PropagateResponseException
. But the latter is considered an "intermediate solution only".
If I return a PSR-7 Response directly, it (predictably) results in an exception as we already know that a string is expected:
Object of class TYPO3\CMS\Core\Http\RedirectResponse could not be converted to string
So what can you do? Is there a sustainable way to issue an HTTP redirect in this scenario? And if not, what else can you do? One could return a dummy page and work with an onload Javascript redirect or try a redirect meta header in HTML. But these are all pretty ugly approaches IMHO.
答案1
得分: 1
以下是您要翻译的内容:
解决方案1(推荐):
如文档中所示,使用 PropagateResponseException
$responseFactory = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(
\Psr\Http\Message\ResponseFactoryInterface::class
);
$response = $responseFactory
->createResponse()
->withAddedHeader('location', 'https://example.com');
throw new \TYPO3\CMS\Core\Http\PropagateResponseException($response);
如果 USER_INT UserFunctions 能够处理 PSR-7 兼容的响应对象,并且不再支持抛出 PropagateResponseException
,则您只需要删除异常处理并返回响应。
删除:
throw new \TYPO3\CMS\Core\Http\PropagateResponseException($response);
替换为:
return $response;
解决方案2:
如果您真的不想使用 PropagateResponseException
,那么可以返回一个脚本标签。不确定是否在所有浏览器中都有效,但应该可以。
return '<script type="text/javascript">location.href = "https://example.com";</script>';
英文:
There are only two clean solutions to achive a redirect in a USER_INT plugin.
Solution 1 (recommended):
As shown in the docs use the PropagateResponseException
$responseFactory = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(
\Psr\Http\Message\ResponseFactoryInterface::class
);
$response = $responseFactory
->createResponse()
->withAddedHeader('location', 'https://example.com');
throw new \TYPO3\CMS\Core\Http\PropagateResponseException($response);
If USER_INT UserFunctions will be able to handle a PSR-7 compliant response objects and the possibility to throw a PropagateResponseException will be removed. The only thing you have to do is to remove the exception-casting and return the response.
remove:
throw new \TYPO3\CMS\Core\Http\PropagateResponseException($response);
replace by:
return $response;
Solution 2:
If you really not want to use the PropagateResponseException. Then you could return a script tag. Not sure, if this works in all browsers - But should.
return '<script type="text/javascript">location.href = "https://example.com";</script>';
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论