-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
Add support for nesting embeddables #1105
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -142,14 +142,22 @@ protected function doLoadMetadata($class, $parent, $rootEntityFound, array $nonS | |
} | ||
|
||
if (!$class->isMappedSuperclass) { | ||
|
||
foreach ($class->embeddedClasses as $property => $embeddableClass) { | ||
|
||
if (isset($embeddableClass['inherited'])) { | ||
continue; | ||
} | ||
|
||
if ($embeddableClass['class'] === $class->name) { | ||
throw MappingException::infiniteEmbeddableNesting($class->name, $property); | ||
} | ||
|
||
$embeddableMetadata = $this->getMetadataFor($embeddableClass['class']); | ||
|
||
if ($embeddableMetadata->isEmbeddedClass) { | ||
$this->addNestedEmbeddedClasses($embeddableMetadata, $class, $property); | ||
} | ||
|
||
$class->inlineEmbeddable($property, $embeddableMetadata); | ||
} | ||
} | ||
|
@@ -370,6 +378,34 @@ private function addInheritedEmbeddedClasses(ClassMetadata $subClass, ClassMetad | |
} | ||
} | ||
|
||
/** | ||
* Adds nested embedded classes metadata to a parent class. | ||
* | ||
* @param ClassMetadata $subClass Sub embedded class metadata to add nested embedded classes metadata from. | ||
* @param ClassMetadata $parentClass Parent class to add nested embedded classes metadata to. | ||
* @param string $prefix Embedded classes' prefix to use for nested embedded classes field names. | ||
*/ | ||
private function addNestedEmbeddedClasses(ClassMetadata $subClass, ClassMetadata $parentClass, $prefix) | ||
{ | ||
foreach ($subClass->embeddedClasses as $property => $embeddableClass) { | ||
if (isset($embeddableClass['inherited'])) { | ||
continue; | ||
} | ||
|
||
$embeddableMetadata = $this->getMetadataFor($embeddableClass['class']); | ||
|
||
$parentClass->mapEmbedded(array( | ||
'fieldName' => $prefix . '.' . $property, | ||
'class' => $embeddableMetadata->name, | ||
'columnPrefix' => $embeddableClass['columnPrefix'], | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. shouldn't both column prefixes be concatenated when nesting ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think so. How would you expect to concatenate here? We don't know the naming strategy to use. Also if you have a look at the tests, it is working as expected IMO. The concatenation is done here. |
||
'declaredField' => $embeddableClass['declaredField'] | ||
? $prefix . '.' . $embeddableClass['declaredField'] | ||
: $prefix, | ||
'originalField' => $embeddableClass['originalField'] ?: $property, | ||
)); | ||
} | ||
} | ||
|
||
/** | ||
* Adds inherited named queries to the subclass mapping. | ||
* | ||
|
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.
this is not the only case leading to an infinite nesting. You need to account for loops as well:
A embed B embed A
(and with any length for the cycle of course)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.
A good way to solve this is to keep an internal reference map (new property in the CMF) somehow. Finding loops would be easy then.
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.
You're right, I almost expected to be missing something here. Meh that is tricky... Have to think about a reasonable solution 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.
private $embeddablesInheritance = [];
and thenSomething like that. I suggest starting from a test, as it makes it much easier to write the recursion
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.
@Ocramius thanks I will try that.
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.
Another data structure would maybe even be cleaner: could just be a small,
final
InheritanceMap
object/utility