-
-
Notifications
You must be signed in to change notification settings - Fork 896
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
Rework of Doctrine ItemDataProvider #458
Conversation
} | ||
|
||
if ($resourceManager instanceof EntityManagerInterface) { | ||
// TODO: check if $resourceClass is good here |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO to be checked: @dunglas you're probably more familiar than me on that one
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could also check against the method, not sure
In blocked state:
|
{ | ||
$repository = $resourceManager->getRepository($resourceClass); | ||
|
||
if ($repository instanceof EntityRepository) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dunglas should I check against EntityRepository
or try if it has the createQueryBuilder()
method?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Prefer class_exists
it will allow custom implementations to work too.
24d1fbc
to
2239a39
Compare
ping @dunglas updated the querybuilder part, tell me if it's good for you and I'll add unit tests afterwards |
@theofidry I made a use case that broke in v1 due to composite identifiers, feel free to use the behat test case I wrote :). |
@soyuka neat, will look into it as soon as I can :) |
* @return \Doctrine\ORM\QueryBuilder | ||
*/ | ||
private function retrieveQueryBuilder(ObjectManager $resourceManager, string $resourceClass) | ||
{ | ||
$repository = $resourceManager->getRepository($resourceClass); | ||
|
||
if ($repository instanceof EntityRepository) { | ||
if ($repository instanceof EntityRepository) { | ||
return $repository->createQueryBuilder('o'); | ||
} | ||
|
||
if ($resourceManager instanceof EntityManagerInterface) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't you add an or
condition to avoid code duplication below? (same goes for the repository method_exists
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not really because the order matter here:
- try with an
EntityRepository
: optimal case - try with a
EntityManagerInterface
: other optimal case, but requires to do things differently - fallback to check if the repository still have this
createQueryBuilder()
method, and assumes it's the right one (technically there is no guarantee here) - last fallback with the manager before throwing an error
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I find this hack pretty ugly but maybe I missed something, it's been some time since I used Doctrine, would be happy to find a better solution
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm I don't understand why EntityManagerInterface
would take priority upon EntityRepository
if it has a createQueryBuilder
method.
if ($repository instanceof EntityRepository || method_exists($repository, 'createQueryBuilder')) {
return $repository->createQueryBuilder('o');
}
if ($resourceManager instanceof EntityManagerInterface || method_exists($resourceManager, 'createQueryBuilder')) {
return $resourceManager->createQueryBuilder()
->select('o')
->from($resourceClass, 'o');
}
throw new RuntimeException();
I'd add that I find it weird to test that the $resourceManager
has the createQueryBuilder
, especially if it's not implementing the EntityManagerInterface
. IMO this will almost always be false, what's the edge case that I'm missing?
IMO there is no better way of returning a query builder with a select clause on the correct entity, and it's a fine way of doing it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm I don't understand why EntityManagerInterface would take priority upon EntityRepository if it has a createQueryBuilder method.
My thinking was trying to get the most reliable solution first, assuming that the EntityReopsitory::createQueryBuilder()
is right is a baseless assumption with no means to check if it's true. At least with the EntityManagerInterface
it's guaranteed to work.
I'd add that I find it weird to test that the $resourceManager has the createQueryBuilder, especially if it's not implementing the EntityManagerInterface. IMO this will almost always be false, what's the edge case that I'm missing?
$resourceManager
could simply be a ObjectManager
right?
IMO there is no better way of returning a query builder with a select clause on the correct entity, and it's a fine way of doing it.
I don't have any strong feeling on this, but if you and the others find it better I would be happy to switch to that instead
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
$resourceManager could simply be a ObjectManager right?
Indeed, and the ObjectManager
doesn't provide the createQueryBuilder
method. EntityManagerInterface
extends ObjectManager
, and the createQueryBuilder
method belongs to the EntityManagerInterface
.
As I'm no Doctrine expert, I've no further opinion on this. Hope others will :).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, we got someone who wrote a book on it right @dunglas?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've read one more time and it does make sense in some way :). Does this patch also applies to the CollectionDataProvider?
ping @dunglas |
@api-platform/core-team there is one last point for which I'm not sure of the behaviour we should adopt, see the discussion with soyuka. Could you check that so that I fix this and rebase this PR? |
ping @api-platform/core-team: there is just one part left, could you guys check it please? |
|
||
/** | ||
* @param ManagerRegistry $managerRegistry | ||
* @param PropertyNameCollectionFactoryInterface $propertyNameCollectionFactory | ||
* @param PropertyMetadataFactoryInterface $propertyMetadataFactory | ||
* @param QueryItemExtensionInterface[] $itemExtensions | ||
* @param ItemDataProviderInterface|null $decorated | ||
* @param ItemDataProviderInterface|null $decoratedProvider |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We're naming this decorated
in every other class, why change it here?
2239a39
to
6b6c5a8
Compare
Updated |
@dunglas is that still relevant? i.e. is it still worth to rebase it? |
@theofidry Honestly I don't know. WDYT? |
Let me check it when I'm back in London (Tuesday), any opinion before that On Saturday, 20 August 2016, Kévin Dunglas [email protected] wrote:
|
Maybe we can close this one? |
I don't really have time to take a look at it again so yeah let's do that. The problem may not be solved but I don't see any API change so that's something that could easily come as a patch if a problem were to occur. |
The objective of this PR is to: