如何将已弃用的HttpUtility::redirect()替换为在传统TYPO3插件中使用的PSR-7响应?

huangapple go评论68阅读模式
英文:

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.

[1] https://docs.typo3.org/c/typo3/cms-core/main/en-us/Changelog/11.3/Deprecation-94316-DeprecatedHTTPHeaderManipulatingMethodsFromHttpUtility.html

英文:

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] https://docs.typo3.org/c/typo3/cms-core/main/en-us/Changelog/11.3/Deprecation-94316-DeprecatedHTTPHeaderManipulatingMethodsFromHttpUtility.html

答案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
    -&gt;createResponse()
    -&gt;withAddedHeader(&#39;location&#39;, &#39;https://example.com&#39;);

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 &#39;&lt;script type=&quot;text/javascript&quot;&gt;location.href = &quot;https://example.com&quot;;&lt;/script&gt;&#39;;

huangapple
  • 本文由 发表于 2023年4月1日 00:34:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/75900827.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定