Background
I am developing an application using Symfony 2 that is structured such that a "Core" bundle defines entities, relationships and fields. Other bundles are then be able specialise the core functionality by inheritance, so-called "child" bundles.
Doctrine 2 annotations have been used to define a core entity called "Package". A "Package" links together an architectural design and a piece of land - essentially a house-and-land package. I've cut the examples back to a more basic form, so you won't find definitions for Land and ChildLand in the examples below, but you can assume they have been implemented in a similar fashion.
Update
According to users on FreeNode's #symfony channel, this is a doctrine issue as the app/console command simply invokes the doctrine console. I am using doctrine 2.3.
Here is a diagram showing the general situation that causes the issue which should help visualise the scenario:
(imgur link to full-size image)
Also, here is a link to a bug report on doctrine's issue tracker: http://www.doctrine-project.org/jira/browse/DDC-2605
Update 2 - More detailed ERD
The structure of the relationships between entities has been questioned, so below is a better example of the data structure we are implementing.
The main requirement is again to have core classes that provide a shared set of entities and fields. Child classes in company bundles extend these core classes.
We did consider EAV at length, but in that approach we will spend a lot more time creating a platform and the tools to manage EAV data rather than satisfying the present business requirements, we won't be able to use doctrine to manage the entities as they will be defined in the database, etc etc.
As time passes and I come to understand this issue better, it appears the only issue is with the getters and setters generated by doctrine's CLI tool as they break the type hinting contracts as mentioned below. This structure works perfectly when these issues are manually corrected.
(imgur link to full-size image)
Generating Entities with CLI Tool
So, initially I used the command line tool...
> app/console doctrine:generate:entity
...to generate the entity stubs with basic field mappings, then manually added the relationship to land (as the tool doesn't seem to support relationships):
This is the resulting code:
core Package entity: http://pastebin.com/3ujPT1mJ
child Package entity: http://pastebin.com/sjAB0XJ2
Generating Getters and Setters
Next, I generate the getters and setters by executing:
> app/console doctrine:generate:entities CompanyCoreBundle
> app/console doctrine:generate:entities CompanyChildBundle
Which automatically modifies the core and child entity definitions:
core Package entity: http://pastebin.com/kfQRxcnm
child Package entity: http://pastebin.com/UdiPP9xX
The problem!
So, the crux of the issue is this: If you compare the setLand function in the Core and Child bundle, you can see the declarations are different:
public function setLand(\Company\CoreBundle\Entity\Land $land = null)
public function setLand(\Company\ChildBundle\Entity\ChildLand $land = null)
Errors :(
Unfortunately, the different type hints cause PHP strict errors to occur, for example:
PHP Fatal error: Class 'Symfony\Component\Debug\Exception\ContextErrorException' not found in ... Company/ChildBundle/Entity/ChildPackage.php on line ...
And
Runtime Notice: Declaration of ... should be compatible with ... in ... line ...
The cause of the errors
After doing some research as to why this was a problem, I read in several places that changing type hinting in subclasses breaks type hinting contracts (see this post: Is there a way to redefine a type hint to a descendant class when extending an abstract class?).
Options?
There are some obvious but less-than-ideal options:
My question!!! (finally)
My question is, is it possible to use the command line tools to do what I am trying to do here? Ideally, I'd love to be able to execute the doctrine console commands to generate entity stubs and getters and setters without manual intervention to fix up type hints in sub-classes. If this isn't easily achievable, what's the next-best option?
Gratitude
Thanks!
I'm not exactly sure what process you'll use in order to define the entities, but in order to usefully create persistable entities with Doctrine such as GenericEngine and FordEngine, you want @MappedSuperclass
http://docs.doctrine-project.org/en/latest/reference/inheritance-mapping.html#mapped-superclasses
It's the Doctrine equivalent of an abstract class.
There are some other interesting inheritance tricks on that page linked above. They might help you.
As far as generating this stuff automatically, it could be doable but above my pay grade at +50 reputation points. :-) Doctrine can help you generate code templates for your entities, but really, time designing the entities and their relationships is better spent than time coming up with a magic command line combination.
(Myself, I'd have a Manufacturer
entity and then have one-to-many relationship between the Engine
and the Manufacturer
. But that's not what you asked. :-)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With