Bug #106174
openCan not create BE links between Extbase modules using f:link.action view-helper if enableNamespacedArgumentsForBackend is disabled
0%
Description
I'm in a backend Extbase AccountingModule and try to link with ''f:link.action()'' from a list-view of invoices to another BE module named UserModule (to show the related user of an invoice):
<f:link.action controller="Backend\UserModule\User" action="show" arguments="{user: invoice.user.uid}"
pluginName="vendor_MyCoreUser" class="btn btn-default btn-sm" title="Show user">
<core:icon identifier="actions-view-page"/>
</f:link.action>
The problem is, that the URL is never generated, only the icon file is shown.
During debugging we found the issue in Extbase's ''UriBuilder'', because it derives a route-identifier for the current route (AccountingModule), which results in a wrong route-identifier construction with the passed view-helper arguments:
UriBuilder line 620: get the current route-identifier
if (($route = $request?->getAttribute('route')) instanceof Route) {
$arguments['route'] = $route->getOption('_identifier');
}
UriBuilder line 628: The variables having the following values:
$routeIdentifier: String 'vendor_MyCoreAccounting.Backend\AccountingModule\Invoice_list' $arguments: Array ( [user] => 123 [action] => show [controller] => Backend\UserModule\User )
UriBuilder line 637: Because the route contains a dot, the route is exploded to get the prefix-part of the CURRENT route identifier:
$routeIdentifier: String 'vendor_MyCoreAccounting'
UriBuilder line 642: The wrong current route-prefix is now combined with the given view-helper $arguments for the other module:
$routeIdentifier: String 'vendor_MyCoreAccounting.Backend\UserModule\User_show'
And this is the issue, because this route-identifier does not exists! The expected value would be ''vendor_MyCoreUser.Backend\UserModule\User_show'', like given to the view-helper in "pluginName" argument.
We thought, it might work if the "enableNamespacedArgumentsForBackend" feature is enabled for both modules, but the issue is similar: yes, with this feature enabled the URL is generated at least, BUT not working, because its linking still to the wrong module (but has the correct URL parameter):
''https://project.ddev.site/typo3/module/vendor/MyCoreAccounting?tx_mycore_mycoreuser%5Baction%5D=show&tx_mycore_mycoreuser%5Bcontroller%5D=Backend%5CUserModule%5CUser&token=...'' (expected URL: ''.../module/vendor/MyCoreUser?...'')
How to fix the issue:
If "enableNamespacedArgumentsForBackend" feature is disabled (default), we simply pass the ''$pluginName'' as "route" to ''$prefixedControllerArguments'':
$prefixedControllerArguments = $controllerArguments;
$prefixedControllerArguments['route'] = $pluginName; // FIX (added in line 538 of UriBuilder)
Later in ''$this->buildBackendUri()'' method, this "route" value overwrites the route-identifier which was derived from the ''$request'' using ''array_replace_recursive()'', and that fixes the issue.
From my understanding there shouldn't be any side-effects with this solution, since ''$pluginName'' is always set by ''$this->request->getPluginName()'' if not given (null), and this value is always equivalent with the dot-prefix of ''$request?->getAttribute('route')'' of the current route.
Updated by Garvin Hicking about 1 month ago
Would you like to create/propose a patch for this maybe? Thanks for taking the time for a detailed inspection!
Updated by Gerrit Code Review about 1 month ago
- Status changed from New to Under Review
Patch set 1 for branch main of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at https://review.typo3.org/c/Packages/TYPO3.CMS/+/88211
Updated by Bastian Stargazer about 1 month ago
ยท Edited
I just see that 7 Unit tests failing with this patch. But I've tested in a pretty big project where it seems to work. Not sure if the Unit tests have to be adjusted as well,...
Can someone which a deeper understanding of the UriBuilder look at it?
Updated by Garvin Hicking about 1 month ago
Yes, the tests have fixture expectations and now that "route" is always set, they would need to also contain this expected array key in the output.
I wonder though - this routing is meant for extbase backend plugins, but the way I read the patch it seems as if this array key would also be attached to f:link.action usages in the frontend?
Updated by Bastian Stargazer 10 days ago
Garvin Hicking wrote in #note-4:
I wonder though - this routing is meant for extbase backend plugins, but the way I read the patch it seems as if this array key would also be attached to f:link.action usages in the frontend?
Thank you for your feedback. I'm not exactly sure what you mean, as the patch modifies the if-else-condition !$isFrontend
, so from my understanding this should not be true during frontend usages?!
} elseif (!$isFrontend) {
$prefixedControllerArguments = $controllerArguments;
$prefixedControllerArguments['route'] = $pluginName; // fixed by patch
}
Updated by Garvin Hicking 10 days ago
You are right - I didn't check properly enough.
Are you able to adjust the fixtures or would you like to get help? :)
Updated by Bastian Stargazer 10 days ago
Garvin Hicking wrote in #note-6:
Are you able to adjust the fixtures or would you like to get help? :)
I looked into the tests after they failed and had no clue at all whats going on there (also because I'm not very familiar with testing -- I know, its a shame^^).
So I'd highly appreciate if you could tell me what I need to do (Or if you can add the changes to the patch directly)
Updated by Garvin Hicking 10 days ago
We had a small chat, just for any people looking at this, here's the (translated) transcript:
OK, I'll try to explain it. It looks more complicated than it actually is.
When you look at the CI failure, you end up here:
[CI Job Link](https://git.typo3.org/typo3/CI/cms/-/jobs/4197984)
In total, six error messages are displayed, all of which are similar:
- `TYPO3\CMS\Extbase\Tests\Unit\Mvc\Web\Routing\UriBuilderTest::uriForPrefixesArgumentsWithExtensionAndPluginNameAndSetsControllerArgument`
- `TYPO3\CMS\Extbase\Tests\Unit\Mvc\Web\Routing\UriBuilderTest::uriForRecursivelyMergesAndOverrulesControllerArgumentsWithArguments`
and so on.
Fortunately, all error messages are thrown in a single test file:
`typo3/sysext/extbase/Tests/Unit/Mvc/Web/Routing/UriBuilderTest.php`
And all the tests are essentially the same; "expectations" are not met because an array key `"route"` suddenly appears and is included, which is not present in the fixtures (which are essentially "templates," usually stored in a CSV file).
The first step is to check in which files the fixtures are defined so that they can be adjusted.
For the last error message in this case, the expectation is not created via a CSV file but rather through a simple array:
```php
$expectedArguments = ['controller' => 'SomeController'];
```
This line needs to be adjusted to:
```php
$expectedArguments = ['controller' => 'SomeController', 'route' => 'SomePluginNameFromRequest'];
```
Similarly, you need to look at the listed line numbers in the other five code locations and check where the expectation is being set "nearby."
Then, insert the key, which you can conveniently see directly in the error message.
(In all other cases, `'route' => 'SomePlugin'` should be used.)
Updated by Gerrit Code Review 10 days ago
Patch set 2 for branch main of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at https://review.typo3.org/c/Packages/TYPO3.CMS/+/88211
Updated by Gerrit Code Review 10 days ago
Patch set 3 for branch main of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at https://review.typo3.org/c/Packages/TYPO3.CMS/+/88211
Updated by Gerrit Code Review 10 days ago
Patch set 1 for branch main of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at https://review.typo3.org/c/Packages/TYPO3.CMS/+/88505