diff --git a/Annotation/Embedded.php b/Annotation/Embedded.php index cc3513b6..b6a88eca 100644 --- a/Annotation/Embedded.php +++ b/Annotation/Embedded.php @@ -27,4 +27,6 @@ final class Embedded extends AbstractAnnotation implements PropertiesAwareInterf * @Doctrine\Common\Annotations\Annotation\Required */ public $class; + + public $singular = false; } diff --git a/Mapping/Converter.php b/Mapping/Converter.php index 2d265f93..d7dce764 100644 --- a/Mapping/Converter.php +++ b/Mapping/Converter.php @@ -87,13 +87,18 @@ protected function denormalize(array $raw, string $namespace) $setter = $fieldMeta['setter']; if ($fieldMeta['embeded']) { - $this->addClassMetadata($fieldMeta['class'], $fieldMeta['sub_properties']); - $iterator = new ObjectIterator($fieldMeta['class'], $value, $this); + $this->addClassMetadata($fieldMeta['class'], $fieldMeta['sub_properties']); - if ($fieldMeta['public']) { - $object->{$fieldMeta['name']} = $iterator; + if ($fieldMeta['singular']) { + $object->$setter($this->denormalize($value, $fieldMeta['class'])); } else { - $object->$setter($iterator); + $iterator = new ObjectIterator($fieldMeta['class'], $value, $this); + + if ($fieldMeta['public']) { + $object->{$fieldMeta['name']} = $iterator; + } else { + $object->$setter($iterator); + } } } else { if ($fieldMeta['type'] == 'date') { diff --git a/Mapping/DocumentParser.php b/Mapping/DocumentParser.php index fa1c2d88..78f1e917 100644 --- a/Mapping/DocumentParser.php +++ b/Mapping/DocumentParser.php @@ -130,6 +130,7 @@ private function getClassMetadata(\ReflectionClass $class): array $fieldMapping['type'] = $this->getObjectMappingType($embeddedClass); $fieldMapping['properties'] = $this->getClassMetadata($embeddedClass); $embeddedFields[$name] = $annotation->class; + $embeddedFields['singular'] = $annotation->singular; } $mapping[$annotation->getName() ?? Caser::snake($name)] = array_filter($fieldMapping); @@ -207,6 +208,7 @@ public function getPropertyMetadata(\ReflectionClass $class, bool $subClass = fa if ($annotation instanceof Embedded) { $propertyMetadata['embeded'] = true; $propertyMetadata['class'] = $annotation->class; + $propertyMetadata['singular'] = $annotation->singular; $propertyMetadata['sub_properties'] = $this->getPropertyMetadata( new \ReflectionClass($annotation->class), true diff --git a/Resources/doc/mapping.md b/Resources/doc/mapping.md index 0722b74b..5674ac96 100644 --- a/Resources/doc/mapping.md +++ b/Resources/doc/mapping.md @@ -209,26 +209,31 @@ class Product /** * @var ContentMetaObject * - * @ES\Embedded(class="App\Document\CategoryObject") + * @ES\Embedded(class="App\Document\CategoryObject", singular=true) */ private $category; //... - public function __construct() + public funtion setCategory($category) { - $this->category = new ArrayCollection(); + $this->category = $category; } - public funtion addCategory($category) + public function getCategory($category) { - $this->category->add($category) + return $this->category; } //... } ``` +Please note that if you want the category to be embedded as a singular +object (not an array of objects), you need to use the `singular=true` in the +annotation, otherwise it will be interpreted as a collection. Read more on +embedding collections bellow. + And the `Category` object will look like (it's a separate class): ```php