Open frankdekker opened 1 year ago
Haven't investigated further yet, but this option makes some OrderFilters disappear in my current project too.
Actually same exact problem here, the ApiResources having this problem have double uppercase letters in their names...
Exactly the same for me (filters are ignored when keepLegacyInflector is set to false and the name contains 2 consecutive uppercases or more).
I'm not convinced by the conclusion that Inflector::tableize should do the same thing if keep_legacy_inflector is set to true or false. there is an if/else The solution depends on what the keepLegacyInflector is supposed to do. Maybe it's normal that the legacy inflector doesn't do the same than the new one. The problem is that the new one is not used at every step when we set keepLegacyInflector to false.
There is 3 Inflectors Doctrine\Inflector\Inflector ApiPlatform\Util\Inflector (redirect all method calls to Doctrine\Inflector\Inflector) ApiPlatform\Metadata\Util\Inflector (has it's own implementation, redirect method calls to Doctrine\Inflector\Inflector only if the keep_legacy_inflector option is set to true)
During serviceLocator initialization, we use ApiPlatform\Util\Inflector ; so the legacy one is used, and our filters are stored with the legacy naming convention
At the moment we create the context to inject it into the Operation, we use ApiPlatform\Metadata\Util\Inflector to retrieve the instance of our filters, and we obtain a name following the new convention.
And later we always 'continue' because their is no registered filter with the given name
Other possible solution : add a use statement to replace ApiPlatform\Util\Inflector by ApiPlatform\Metadata\Util\Inflector
Other possible solution : change the code of ApiPlatform\Util\Inflector to do the same than ApiPlatform\Metadata\Util\Inflector ; but it will still be strange to have 2 inflectors that do the same thing, I wonder what is the reason why those 2 Inflector classes coexist.
@soyuka what do you think ? Is it good ideas ? If you think I'm on the right way I'd be happy to make a PR.
Hi, ApiPlatform\Util\Inflector
is deprecated. We should definitely always go to the new inflector or the one you choose please open a PR.
Same issue here. Any news?
Im actually seeing a very similar issue.
keep_legacy_inflector
to false
Im actually seeing a very similar issue.
- Set
keep_legacy_inflector
tofalse
- The API resources are not multiple capital letters in a row however
- Custom filters are not getting triggered. Built in ones are.
I was wrong, there was a Multiple Capital letters in a row in the namespace
@jonnyeom the fix of december 2023 was actually to handle this multiple capital letters case. But unfortunatly, it seems that there is an other issue with that in production environment only with cache generation.
How to reproduce (tested with apiPlatform 3.2 and 3.3): Set APP_ENV=prod Create a resource with custom filters in the DTO namespace (or any namespace with consecutive capital letters) Remove your cache, and execute php bin/console -v (or any command but debug:router) The cache is re-generated by this command, Then somewhere in var/prod/cache/pools/system there is a file describing the User resource, transforming DTO to d_t_o (INCORRECT ==> see the left part of the illustration bellow) Remove your cache, and execute php bin/console debug:router The cache is re-generated by this command, Then somewhere in var/prod/cache/pools/system there is a file describing the User resource, transforming DTO to d_t_o (CORRECT ==> see the right part of the illustration bellow)
Of course, once the cache is incorrectly generated, in production environment it stays in the same state forever.
Maybe I'll try to create a new MR for this case, but in the meantime I guess avoiding consecutive uppercases is the workaround. Renaming my DTO namespace to DataTransferObject fixes the problem but not the cause of the problem obviously.
For now, we could change our namespace.
But this is a really weird issue with non-consistent behavior between environments. I think it should be looked into
@celinederoland
I was able to reproduce it in my APP_ENV=test
environment by building cache twice. (i.e. bin/console cache:warm --env=test
x2)
The first time, the filters are cached into the container and the Inflector class uses the correct ApiPlatform\Metadata\Util\Inflector::$keepLegacyInflector = false
from configuration (set to keep_legacy_inflector=false).
But when I run cache:warm a second time, the same static instance of the Inflector class has ApiPlatform\Metadata\Util\Inflector::$keepLegacyInflector = true
I didnt get to the nitty-gritty of what is underscoring it exactly, but..
With Api-Platform 3.4.x #6447 introduces Inflector as a service and correctly sets ::$keepLegacyInflector
each time.
In fact \ApiPlatform\Metadata\Util\AttributeFilterExtractorTrait::generateFilterId()
doesnt even use that service anymore.
Just upgrading to 3.4.x should fix this specific issue. The environment inconsistencies of the Inflector class should be fixed with the new change anyway.
API Platform version(s) affected: v3.2.3
Description Below a (slimmed down) example of our entity and ApiPlatform resource and filter definition:
When I toggle
keep_legacy_inflector
setting tofalse
the search filter will disappear from the documentation and api.How to reproduce
Create the entity above and set
keep_legacy_inflector
to false. Keep an eye on the namespace. The namespace must with start 2 capital letters.Possible Solution
I've tracked down the problem to:
vendor/api-platform/core/src/Metadata/Util/Inflector.php
in thetableize
method. See phpunit test below for the difference in output. It seems that the(new UnicodeString($word))->snake()->toString()
does not return the exact same output as the original tableize method. Handling multiple sequential uppercase letters differently.PHPUnit test that reproduces the problem:
Additional Context