
PHPStan findings - missing capabilities for autocompletion / generation?

We have the behaviour, that phpstan is complaining about missing methods for the autogenerated locator file:
Call to an undefined method Generated\Client\Ide\AutoCompletion&Spryker\Shared\Kernel\LocatorLocatorInterface::niceFeature()
while we wanna access it with
$container->getLocator()->niceFeature()->client();
I dug a bit deeper and saw, this is a feature/module only available for a specific store, so there is a "NiceFeatureUS" module, but no "NiceFeature" module …
Question: Is it mandatory to name the auto-resolved files (factories, facades etc.) in those bundles also with a suffix to match it in the autocompletion or in general? (e.g. NiceFeatureUSClient)
I assumed up to here that for example the generator (as the class resolver) would remove the bucket part "US" and search for a class called "NiceFeatureClientInterface". But actually it searches for "NiceFeatureUSClientInterface", which indeed does not exist on our side. Is this intended to have suffixed class names also?
If not, how to solve this?
Best regards
Comments
-
Following Spryker's convention, the interface and class should be named after the module, so:
NiceFeatureUSClientInterfaceNiceFeatureUSClient for the class. The same goes for the rest of the files like DependencyProvider, Configs, etc.
0 -
Hey @Hidran Arias ,
thanks for your response.
When the convention is like this, I still wonder why the resolver classes are capable of resolving store suffixes like "US", but the IDE auto generator is not. Or is this a leftover?
0 -
I fiddled around a bit and it seems, that for NiceFeatureUS the class NiceFeatureUSClientInterface is not found where NiceFeatureClient was found before.
The found "candidates" in the resolver classes are just listing them without the bucket. part
So i think there is still a gap or i do really miss some key concepts.
Best regards
0 -
I created a NiceFeature and NiceFeatureUS client ( spryk-run AddClient —module NiceFeatureUS)
I then added NiceFeatureUS Client to Yves' ProductDetailPageDependencyProvider .
I ranconsole dev:ide-auto-completion:generate
and I'm having autocompletion and no phpstan issues
Did you run the cache:class-resolver:build and the autocompletion one?0 -
Hi Hidran,
first, thanks for your effort trying to reproduce this.
I am not sure what exactly was reproduced on your side, but i guess its a different use case.
Its not about adding the "NiceFeatureUS" Client (Pyz\Client\NiceFeatureUS\Client) to any dependency provider directly.
Its about adding the "NiceFeature" Client (Pyz\Client\NiceFeature\Client) to it but getting the "NiceFeatureUS" Client (Pyz\Client\NiceFeatureUS\Client) ultimately, because its a specific implementation only valid for the current bucket (e.g store).
What i investigated from the code side is that when the dependency (in this case via ClientResolver) is getting resolved, it looks for a bucket/store specific implementation with
protected function getCurrentApplicationsCodeBucket(): string { return $this->isApplicationCodeBucketDefined() ? APPLICATION_CODE_BUCKET : ''; }
So whenever there is a "NiceFeatureUS" module found and the current bucket is "US", any call regarding "NiceFeature" is using this bucket specific implementation.
But …
the auto generation do not find it, since it will not care about any buckets and module suffixes when looking for the specific classes …
As a false positive result I can just imagine, if you would have "Pyz\Client\NiceFeature\Client" and also a "Pyz\Client\NiceFeatureUS\Client", the ide auto generator will find it, because it matches the base "Pyz\Client\NiceFeature\Client" in any case.
But when you only have a store specific implementation, it will not match it (thats our use case here).
Also i would guess that whenever you extend the store/bucket speific client with another method, its not found, but not sure about that …
Hopefully this was a bit more clear?
Best regards
0 -
I get it now!
So, you don't have the NiceFeature/Client but you created a Codebucket.
You create a code bucket when you want to override the main module but if you don't have a main module, then you don't need a code bucket but an ordinary client that you would inject in your NiceFeatureUS dependencyProvider, for example in Yves or Glue, with $container->getLocator()->niceFeatureUS()->client();
but the module would have a NiceFeatureUSClient class and interface instead of NiceFeatureClient as it would be an ordinary Client and not an overriding code bucket client, where only the Folder changes
If you anyway want to have it as codebucket then:
Create the main Module, Client/NiceFeature with the implementation that would be shared by the whole app
then in the Client/NiceFeatureUS you would extend (or replace) the main module Client and do what is just needed for the US bucket.0 -
Hi Hidran,
you are absolutely right, overriding a module that has no "base" is pointless. Since we owned this legacy code, we might have to review the whole code again and refactor it carefully. I could also think of a leftover where the whole feature was removed overall but should be kept for a single country ..
There is just one point where i think, the PHPStan errors won't be solved anyway.
Imagine again the usual code bucket scenario with a client in the "NiceFeature" module and a US Specific Client in the "NiceFeatureUS" bucket.
When the "NiceFeautureClientInterface" in "NiceFeatureUS" now has a new method "newUsSpecificMethod()", this won't be detected by the autocompletion (since it does not care about buckets) and therefore always come up as "method not found" error in PHPStan whereever you use it.
My explanation for this is, that from sprykers perspective codebucket interfaces are not intended to be extended (e.g. adding new methods, modifying signatures etc.), but only may implement the existing methods in a different way.
Is this assumption correct? On the other hand, if this would be the rule, a lot of flexibility would be lost imo.
0 -
The method does get autocompleted inside the code bucket because you type hint with the NiceFeatureInterface in that code bucket.
On the other hand, phpstan is a static analyzer and code buckets are determined at run time, so, phpstan doesn't know anything related to code buckets and relies on your type hinting and it should work in your code bucket.
I think the confusion arises when using the code bucket code in some other module not related to the code bucket, by providing it into the dependencyProvider. In that case : That's not the way code buckets are supposed to be used and you should provide the real dependency because you already know which one it is.
I don't see the issue, TBH, as if you use a code bucket, then the code inside that code bucket always refers to classes inside that folder and phpstan wouldn't complaint.
If you then decide to use that codebucket somewhere, the client for example, and you need to provide it through the DependencyProvider of that module, then you should statically specify that dependency because you know it beforehand it the behavior is the normal behavior of any dependency.Code buckets were designed to override the default behavior of the parent code bucket, either the one at project level or the one from the core. You can override anything> Config, Factories,Facades, Clients, DependencyProvider, Controllers, Themes and that's going to be resolved at run time according to the Code Bucket configuration you define in SprykerConfig/CodeBucketConfig .
Anything other than that it's not related to code buckets and follows the normal physical dependencies0
Categories
- All Categories
- 42 Getting Started & Guidelines
- 7 Getting Started in the Community
- 8 Additional Resources
- 7 Community Ideas and Feedback
- 79 Spryker News
- 947 Developer Corner
- 805 Spryker Development
- 91 Spryker Dev Environment
- 362 Spryker Releases
- 3 Oryx frontend framework
- 35 Propel ORM
- 68 Community Projects
- 3 Community Ideation Board
- 30 Hackathon
- 3 PHP Bridge
- 6 Gacela Project
- 26 Job Opportunities
- 3.2K 📜 Slack Archives
- 116 Academy
- 5 Business Users
- 370 Docker
- 551 Slack General
- 2K Help
- 75 Knowledge Sharing
- 6 Random Stuff
- 4 Code Testing
- 33 Product & Business Questions
- 69 Spryker Safari Questions
- 50 Random