Skip to content

Add dynamic return type extensions for getRepository() methods #8

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed

Add dynamic return type extensions for getRepository() methods #8

wants to merge 2 commits into from

Conversation

tsufeki
Copy link

@tsufeki tsufeki commented Sep 7, 2017

Extract repository class from @Entity annotation and use it as return type of getRepository() methods on EntityManager and ManagerRegistry.

@afurculita
Copy link

Neat. IMO this can be merged. Ping @ondrejmirtes

@ondrejmirtes
Copy link
Member

Hi, my current stance is that this does not work very well because of two things:

  1. It reads and parses annotations above an entity class, but what about other metadata drivers? This should use a completely different approach, asking configured instances of Doctrine classes.
  2. Determining that the return type of a getRepository call is not very useful itself, because the main thing that the developer wants is that the getRepository(Xxx::class)->findOneBy(...) returns Xxx|null, which is not yet possible because of missing generics support in PHPStan.

Please discuss whether I'm right or wrong and why should I merge this despite these points. Thank you.

@bendavies
Copy link

@ondrejmirtes my usecase would be fixing getRepository(Xxx::class)->findXXX where findXXX is a custom method on my repository.

@ondrejmirtes
Copy link
Member

@bendavies Yep, I understand, but your solution does not always work because of point 1.

At least for now I added support for correct return type from getRepository(Xxx::class)->find* methods.

@afurculita
Copy link

@ondrejmirtes you're completely right about 1. My use case is like the one from @bendavies : I have custom methods in repositories, but they do not necessarily start with find. Something like getAllUsersWithSomething.

@ondrejmirtes
Copy link
Member

@afurculita I understand but that's much harder to solve. It'd mean that PHPStan would have to know about part of dependency graph of your application in order to initialize RepositoryFactory, class metadata etc.

I recommend you to access your repositories not through $em->getRepository() but injecting the concrete class directly:

/** @var ArticleRepository */
private $articleRepository;

It will lead to a better code not only for PHPStan, but for your tests as well, you won't have to mock as much.

@koftikes
Copy link

Hello,
I tested this solution and its look good.
Do you planning apply pull request?
Thank you in advance.

@Ocramius
Copy link

Looks wrong to me: the return type of getRepository() is rigid, and if something else is needed, just avoid using getRepository().

I know we added a repository factory and customization to doctrine internals, but that was our mistake that we should fix.

@ondrejmirtes
Copy link
Member

Besides the point #1 from my comment here, if you're in need of this extension, you shouldn't call $em->getRepository(), but inject the specific EntityRepository (or a child class) in your class directly via dependency injection, as @Ocramius said.

BTW: I'm not a fan of extending EntityRepository at all. It encourages huge god objects with many methods because of 1:1 mapping between repositories and entities. I like much more specific repositories for specific use-cases of an entity. For example one repository for getting translations, another repository for tree manipulation etc.

So I reserve my right to be opinionated and close this PR.

@soullivaneuh
Copy link

Can this PR be reconsidered as an option of the plugin?

I fully understand that we should not have lot of custom repositories and the fact that getRepository "is" rigid, but it is not and this is working like that.

At least for old codebase following old conventions, having this PR possible with an option would be a real plus IMHO. 👍

@ondrejmirtes
Copy link
Member

@soullivaneuh If someone finished #18, I'd merge it. The advantage of the more recent PR is that it uses class metadata and is not hardcoded to read annotations.

@curry684
Copy link
Contributor

curry684 commented May 19, 2018

@tsufeki any idea why this doesn't also catch #27? I have all annotations in place.

Edit: duh didn't see this never got merged.

@ondrejmirtes
Copy link
Member

ondrejmirtes commented May 19, 2018 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants