Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

[WCM][DoctrineBridge] Fix UniqueEntity interaction with inheritance#16981

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Conversation

lemoinem
Copy link
Contributor

QA
Bug fix?yes
New feature?no
BC breaks?no
Deprecations?yes, only ifStaticMethodLoader or a custom Constraint Loader is used to loadUniqueEntity constraints
Tests pass?yes
Fixed tickets#16969,#4087,#12573
Dependens on#16978
LicenseMIT
Doc PRN/A

This is the second half of#16969 with the actual fix.

This version of the code is ready for code review. However, since I'm dependent on#16978, I'm leaving the PR as a WIP until the dependence is merged and I rebase the current one on master.

Since I introduce deprecations, I updatedUPGRADE-4.0.md.

  • Manage the case where@UniqueEntity is attached to a non-Entity class


### DoctrineBridge and Validator

* If you were using the `StaticMethodLoader` to create `UniqueEntity`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Isn't is possible to iterate over$metadata->getConstraints() in theStaticMethodLoader in order to avoid this ?

foreach ($metadata->getConstraints()as$constraint) {if ($constraintinstanceof TargetAwareConstraintInterface) {$constraint->target =$metadata->getClassName();    }}

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

It could be, however the current behavior ofStaticMethodLoader is to do the bare minimum and to let the implementation of the loader method do all the heavy lifting work.

That's why I didn't implement the support for TA constraints in there. But, yeah, it could be done, I guess... I will add a note in the other PR.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

PS: The use case would still be possible (and the deprecation still required) for custom constraint loaders, just thought about that...

@ogizanagi
Copy link
Contributor

Won't it be a BC break as this behavior is thecurrent one described in other PRs, whereas the existing behavior until now matches thereal one ?

@lemoinemlemoinemforce-pushed thefix/doctrine-bridge/unique-entity-inheritance branch froma610e22 toe0ff5d5CompareDecember 12, 2015 00:26
@lemoinem
Copy link
ContributorAuthor

Well, the way I see it, it would be a BC break if the previously correct behavior was changed. But since thecurrent behavior is a bug, it is erroneous, so fixing it wouldn't be a BC break.

@lemoinemlemoinemforce-pushed thefix/doctrine-bridge/unique-entity-inheritance branch frome0ff5d5 to2d9946cCompareDecember 12, 2015 00:36
@ogizanagi
Copy link
Contributor

@lemoinem : I've thought about edges cases with this proposal: What if theUniqueEntityConstraint is declared on a parent class, which is not an entity, and thus, does not have a repository ?
This is the case of theFOSUserBundle for instance.

$target = $constraint->target;
/* @var $target string */
if (!$constraint->target) {
@trigger_error('Not providing a target for a UniqueEntity constraint is deprecated since version 3.1 and will be removed in 3.0.', E_USER_DEPRECATED);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

- @trigger_error('Not providing a target for a UniqueEntity constraint is deprecated since version 3.1 and will be removed in 3.0.', E_USER_DEPRECATED);+ @trigger_error('Not providing a target for a UniqueEntity constraint is deprecated since version 3.1 and will be removed in 4.0.', E_USER_DEPRECATED);

(4.0, not 3.0)

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Good Catch. Thank you!

@lemoinemlemoinemforce-pushed thefix/doctrine-bridge/unique-entity-inheritance branch from2d9946c to36f10c9CompareDecember 16, 2015 21:49
@lemoinem
Copy link
ContributorAuthor

Indeed, that's a very good point... I didn't consider it because having a@UniqueEntity on a non-Entity class seems to be a non-sense to me... BTW, what you describe seems to be FOSUB 1 behavior only, FOSUB 2 definesFOS\UserBundle\Model\User as its entity and it's also the class the entity mapping is defined for.

However, that would definitely be a BC Break...

I'm thinking the best way would be to grab the highest parent of the current entity, among the descendants of the target that IS an Entity and use ITS Repository.

By this, I mean, given these classes:

Root (@Entity)| - Base (@UniqueEntity)    | - BaseEntity (@Entity)    |   | - ChildEntity (@Entity)    |       | - MyEntity (@Entity)    | - EntityB (@Entity)    | - EntityC (@Entity)

calling the validator on an instance ofMyEntity would use the Repository ofBaseEntity. This is consistent with the strategy of using the highest possible Repository with respect to the target.

Using the Repository ofRoot could enforce the constraint against values that aren't supposed to be included (i.e. matching against Entities that aren't instances ofBaseEntity).

Trying to compute the exact match (i.e. trying to lookup in the Repositories ofBaseEntity,EntityB andEntityC), while being semantically correct (we match against ALL the entities instance ofBase) seems to be as being highly unreliable since it will depend on which classes have a mapping loaded at the time the Constraint is validated. This could be far from complete and volatile in the case of Annotations Mappings.

@ogizanagi
Copy link
Contributor

FOSUB 2 defines FOS\UserBundle\Model\User as its entity and it's also the class the entity mapping is defined for.

I don't see what you mean. The file I linked above is from the master branch and so is FOSUser 2. :/
The mapping is, indeed, on theFOS\UserBundle\Model\User, as well as the validation constraints, but this class is still abstract and you'll need to extend it. So when calling the validator on your own user, the target will beFOS\UserBundle\Model\User, but this class isn't an entity (just a mapped superclass) and doesn't have a repository.

Your new suggestion seems good to me however.

@lemoinem
Copy link
ContributorAuthor

I was referring toFriendsOfSymfony/FOSUserBundle@047b0e6 which deleted the Entity classes.

Since this commit, inmaster, theDoctrine mapping is now applied onFOS\UserBundle\Model\User instead ofFOS\UserBundle\Entity\User previously. However I just saw it's not an Entity mapping but a Mapped Superclass mapping. So you were right, my bad.

However, having aUniqueEntity constraint on a Mapped Superclass makes more sense than on a class without any kind of mapping. I'm guessing we could deprecate applyingUniqueEntity on a class without mapping. I'm thinking it would be a separate issue, and I'm not sure either whether that could help with the process of discovering the right Repository to use. I'll check during the implementation if it does.

Thank you for the feedback!

@lemoinem
Copy link
ContributorAuthor

After testing (https://github.com/lemoinem/symfony-standard/tree/test/doctrine/mapped-superclass-repository,composer install, Setup DB,bin/console doc:sc:up --force, Insert various Entities (discr may be either "root" or "entity",bin/console test), calling a MappedSuperclass' Repository is perfectly fine, as long as there is a parent entity and the fields the query is based on are defined and mapped and such parent entity.Doctrine documentation does specify that MSC aren't supposed to be query-able.

This doesn't change much to the implementation I intended to put in place.

@lemoinemlemoinemforce-pushed thefix/doctrine-bridge/unique-entity-inheritance branch from36f10c9 to7937237CompareFebruary 2, 2016 21:52
@lemoinemlemoinemforce-pushed thefix/doctrine-bridge/unique-entity-inheritance branch from7937237 to54fc801CompareFebruary 2, 2016 21:59
@lemoinemlemoinemforce-pushed thefix/doctrine-bridge/unique-entity-inheritance branch 2 times, most recently from35d86d9 to2bb4810CompareFebruary 2, 2016 22:14
@lemoinemlemoinem changed the title[WIP][WCM][DoctrineBridge] Fix UniqueEntity interaction with inheritance[WCM][DoctrineBridge] Fix UniqueEntity interaction with inheritanceFeb 2, 2016
@lemoinem
Copy link
ContributorAuthor

OK, I finally had time to write a relevant test case for the repository search.
I used the "highest repository" strategy we discussed. If you have any other feedback, I'd be happy to hear it!

PS: I also took the chance to rebase both PRs. The PHP 5.6 Travis build currently fails because of FrameworkBundle errors which aren't related to this PR.

*
* @return \Doctrine\Common\Persistence\Mapping\ClassMetadata
*/
private function findHighestEntityMetada(ClassMetadataFactory $metadataFactory, $target, $entityClass)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

typo

- findHighestEntityMetada+ findHighestEntityMetadata

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Yup, indeed!
Thanks!

@lemoinemlemoinemforce-pushed thefix/doctrine-bridge/unique-entity-inheritance branch from2bb4810 to3868657CompareFebruary 3, 2016 15:14
@lemoinemlemoinem changed the title[WCM][DoctrineBridge] Fix UniqueEntity interaction with inheritance[WIP][WCM][DoctrineBridge] Fix UniqueEntity interaction with inheritanceFeb 3, 2016
@lemoinemlemoinem changed the title[WIP][WCM][DoctrineBridge] Fix UniqueEntity interaction with inheritance[WCM][DoctrineBridge] Fix UniqueEntity interaction with inheritanceFeb 3, 2016
@fabpotfabpot closed thisOct 14, 2016
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers
No reviews
Assignees
No one assigned
Projects
None yet
Milestone
No milestone
Development

Successfully merging this pull request may close these issues.

5 participants
@lemoinem@ogizanagi@fabpot@javiereguiluz@carsonbot

[8]ページ先頭

©2009-2025 Movatter.jp