Skip to content

[Doctrine-Bridge] add a base compiler pass class to register doctrine mappings #7599

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 3 commits into from
Closed

[Doctrine-Bridge] add a base compiler pass class to register doctrine mappings #7599

wants to merge 3 commits into from

Conversation

dbu
Copy link
Contributor

@dbu dbu commented Apr 8, 2013

Q A
Bug fix? no
New feature? yes
BC breaks? no
Deprecations? not on code, but defining best practices
Tests pass? yes
Fixed tickets
License MIT
Doc PR symfony/symfony-docs#2507

Reusable bundles providing model classes should not rely on the automapping provided by the doctrine bundles. What is more, the same model can often be mapped to Doctrine ORM, MongoODM, CouchODM and PHPCR-ODM.

This pull request adds a base class for a compiler pass that the concrete doctrine bundles extend to provide a default compiler pass that makes it trivial for bundles to register their mappings. See doctrine/DoctrineBundle#177

The FOSUserBundle shows how this would look in practice. See FriendsOfSymfony/FOSUserBundle#1081

I will create the documentation pull request as well as pull requests for the mongo, couch and phpcr bundles once we agree how exactly to do this.

* @param string $enableParameter service container parameter that must
* be present to enable the mapping. Set to false to not do any check.
*/
public function __construct(
Copy link
Member

Choose a reason for hiding this comment

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

@stof will tell you that we do not wrap constructor argument in symfony code base ;)

Copy link
Contributor

Choose a reason for hiding this comment

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

@lyrixx this is valid as there are so many arguments that single line would be massively long.

Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

@lyrixx is right, we don't do this in Symfony.

@jfsimon
Copy link
Contributor

jfsimon commented Apr 8, 2013

I cant wait to see this merged!

@jfsimon jfsimon closed this Apr 8, 2013
@jfsimon jfsimon reopened this Apr 8, 2013
*/
protected function enabled(ContainerBuilder $container)
{
return ! $this->enabledParameter || $container->hasParameter($this->enabledParameter);
Copy link
Member

Choose a reason for hiding this comment

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

there is no whitespace after the ! operator.

@dbu
Copy link
Contributor Author

dbu commented Apr 11, 2013

i fixed the cs issues and did some more cleanup.

@fabpot: may i interpret your feedback as confirmation this is going in the right direction?

to support the annotation and staticphp drivers, we need different buildDriver methods and slightly different parameters. what is the preferred aproach for this? have a BaseRegisterMappingsPass class and 3 extending classes here in the bridge, and then in each of the bundles? or just have the bundles use this as a base class, passing in empty values for mappings and extensions and overwriting the buildDriver method?

@fabpot
Copy link
Member

fabpot commented Apr 11, 2013

@dbu I'm ok with the feature, but I did not had a look at the implementation. @beberlei is probably the one who need to validate the design.

* file that was distributed with this source code.
*/

namespace Symfony\Bridge\Doctrine\DependencyInjection\CompilerPass;
Copy link
Member

Choose a reason for hiding this comment

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

The namespace should be Compiler for consistency

Copy link
Member

Choose a reason for hiding this comment

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

hmm, actually, we already have 1 compiler pass using a different namespace than in bundles :(

Copy link
Contributor Author

Choose a reason for hiding this comment

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

this is why i put it in this folder. was also a bit suprised to see the CompilerPass namespace here, but thought to follow the example. i can move it to Compiler and do a PR to move the other compiler pass too and deprecate the one in CompilerPass if we think this should be fixed at some point.

@beberlei
Copy link
Contributor

+1 from me

@beberlei
Copy link
Contributor

Discussing ways to refactor with @dbu now, regarding the annotations driver

@beberlei
Copy link
Contributor

Found a way with @dbu to refactor the code. Idea: The constructor will accept a fully configured Definition instance and the children of this compiler pass will provide static factory methods to create compiler passes for the different mapping drivers such as Xml, Yaml, Annotations, etc...

@dbu
Copy link
Contributor Author

dbu commented Apr 15, 2013

i updated the PR according to the discussion with @beberlei. i think the only open question is whether to keep this in the CompilerPass namespace or move it to Compiler.

@dbu
Copy link
Contributor Author

dbu commented Apr 17, 2013

i just added a PR on mongodb, the implementation for this PR did not need to change so i guess its good.

should i move this class to the Compiler namespace even though we have an existing CompilerPass namespace? that is, shall we keep inconsistency with the rest of the framework or be inconsistent inside this component?

anything else i should do before we can merge?

@fabpot fabpot closed this in 6b27e12 Apr 18, 2013
@dbu dbu deleted the doctrine-register-mappings-pass branch April 18, 2013 06:36
}

$mappingDriverDef = $this->getDriver($container);
foreach ($container->getParameter($this->managersParameter) as $name => $manager) {
Copy link
Member

Choose a reason for hiding this comment

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

@dbu IMO, the compiler pass should allow to register the mapping for a specific manager instead of the same mapping for all (which is generally a broken case when all managers are applied for the same entity class)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok. how would you do that, have an optional manager name in the constructor that defaults to "default" and then only register with the manager service with that name? on the other hand, how could something like the FOSUserBundle know which manager to use? do we need a configuration parameter there, that again defaults to "default"?

Copy link
Member

Choose a reason for hiding this comment

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

FOSUserBundle already have a config setting for it as it needs to know which manager it should retrieve (defaulting to null as $registry->getManager(null) returns the default manager)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

i will do a new PR to fix this. sorry!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

if i inject the manager name in the constructor, its too early as the compiler pass is created by the bundle class which does not know the configuration. i could make the name of the manager to use yet another option that is read from a container parameter.
or if i could pass around the compiler pass object i could implement a setManagerName method. what would be the clean way to do this?

Copy link
Member

Choose a reason for hiding this comment

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

IMO, using a parameter might be the best way (it would be perfect for FOSUserBundle as we already store it in a parameter anyway).

And the parameter used by default should be the param defining the default manager in Doctrine*Bundle (as it may not be named default)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok, makes sense. i only use the name in the line below, to replace in the driver name pattern, i don't need the actual manager service name.

regarding the problem of default might not be named "default", i would inject two parameters then? the parameter name for an explicit manager name plus the parameter name for a fallback name to use if the default name does not exist? for the orm that would be doctrine.orm.default_entity_manager holding the name of the manager, not the service name right?

Copy link
Member

Choose a reason for hiding this comment

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

yes, indeed. I first thought you could use doctrine.orm.default_entity_manager as default value for the parameter, but it would indeed break if the user parameter contains null for the default. you need to keep the fallback separate

Copy link
Contributor Author

Choose a reason for hiding this comment

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

i created #7755 to hopefully fix the issue

fabpot added a commit that referenced this pull request Apr 21, 2013
This PR was merged into the master branch.

Discussion
----------

fix register mappings pass to only register mappings with one object manager

| Q             | A
| ------------- | ---
| Bug fix?      |  yes
| New feature?  | no
| BC breaks?    | yes (but feature is totally new)
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #7599
| License       | MIT
| Doc PR        | symfony/symfony-docs#2507

This PR fixes the issues @stof discovered in #7599 - we now introduce a way to only register the mappings with one of the object managers.

Commits
-------

fc12bd1 fix register mappings pass to only register mappings with one object manager
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