Sets the entity embed metadata from the metadata mapping.

@param   Metadata\Interfaces\EmbedInterface  $metadata
@param   array                               $embedMapping
@return  Metadata\EntityMetadata
434822
protected function setEmbeds(Metadata\Interfaces\EmbedInterface $metadata, array $embedMapping)
    {
        foreach ($embedMapping as $key => $mapping) {
            if (!is_array($mapping)) {
                $mapping = ['type' => null, 'entity' => null];
            }

            if (!isset($mapping['type'])) {
                $mapping['type'] = null;
            }

            if (!isset($mapping['entity'])) {
                $mapping['entity'] = null;
            }

            if ($metadata instanceof Metadata\EmbedMetadata && $mapping['entity'] === $metadata->name) {
                // This embed meta is referencing itself as an embed property. As such, do not recreate.
                // This prevents infinite recursion.
                $embedMeta = $metadata;
            } else {
                $embedMeta = $this->loadMetadataForEmbed($mapping['entity']);
            }
            if (null === $embedMeta) {
                continue;
            }
            $property = new Metadata\EmbeddedPropMetadata($key, $mapping['type'], $embedMeta, $this->isMixin($metadata));

            if (isset($mapping['serialize'])) {
                $property->enableSerialize($mapping['serialize']);
            }

            $metadata->addEmbed($property);
        }
        return $metadata;
    }
70729
public function getEmbeddedDiscriminatorValue(PropertyMetadata $mapping, $embeddedDocument)
    {
        if (!$mapping->embedded || get_class($embeddedDocument) !== $this->name) {
            throw new \InvalidArgumentException;
        }

        if ($mapping->targetDocument !== null) {
            return null;
        }

        $discriminatorMetadata = $this->getPropertyMetadata($mapping->discriminatorAttribute);
        $discriminatorValue    = $discriminatorMetadata->getValue($embeddedDocument);

        if ($discriminatorValue === null) {
            if ($discriminatorMetadata->discriminatorDefaultValue === null) {
                return null;
            }

            $discriminatorValue = $discriminatorMetadata->discriminatorDefaultValue;
        }

        if (isset($discriminatorMetadata->discriminatorMap[$discriminatorValue])) {
            return $discriminatorMetadata->discriminatorMap[$discriminatorValue];
        }

        return $discriminatorValue;
    }
14457
private function loadEmbedManyCollection(PersistentCollectionInterface $collection)
    {
        $rawData = $collection->getRawData();

        if ($rawData) {
            $mapping = $collection->getMapping();
            $owner   = $collection->getOwner();

            foreach ($rawData as $key => $data) {
                if ($mapping->type === Type::MAP) {
                    $key = (string)$key;
                } else {
                    $key = (int)$key;
                }

                $embeddedDocument = $this->uow->getAssociationPersister()->loadEmbed($mapping, $data, $owner, $key, $collection->isReadOnly());

                if ($mapping->type === Type::MAP) {
                    $collection->set($key, $embeddedDocument);
                } else {
                    $collection->add($embeddedDocument);
                }
            }
        }
    }
764514
private void marshalWithExplodedStrategy(EmbeddedMetadata embeddedMetadata, Object target) {
    try {
      Object embeddedObject = initializeEmbedded(embeddedMetadata, target);
      for (PropertyMetadata propertyMetadata : embeddedMetadata.getPropertyMetadataCollection()) {
        marshalField(propertyMetadata, embeddedObject);
      }
      for (EmbeddedMetadata embeddedMetadata2 : embeddedMetadata.getEmbeddedMetadataCollection()) {
        marshalWithExplodedStrategy(embeddedMetadata2, embeddedObject);
      }
    } catch (Throwable t) {
      throw new EntityManagerException(t);
    }
  }
768823
public function mapEmbedded(array $mapping)
    {
        $this->assertFieldNotMapped($mapping['fieldName']);

        $this->embeddedClasses[$mapping['fieldName']] = array(
            'class' => $this->fullyQualifiedClassName($mapping['class']),
            'columnPrefix' => $mapping['columnPrefix'],
            'declaredField' => isset($mapping['declaredField']) ? $mapping['declaredField'] : null,
            'originalField' => isset($mapping['originalField']) ? $mapping['originalField'] : null,
        );
    }
48175
public function mapOneEmbedded(ClassMetadata $class)
    {
        $this->embedded = true;
        $this->type     = self::TYPE_ONE;

        $this->mapAttribute($class);
    }
420183
private function mapTranslatable(ClassMetadata $metadata)
    {
        // In the case A -> B -> TranslatableInterface, B might not have mapping defined as it
        // is probably defined in A, so in that case, we just return.
        if (!isset($this->mappings[$metadata->name])) {
            return;
        }

        $config = $this->mappings[$metadata->name];
        $mapping = $config['translation']['mapping'];

        $metadata->mapManyEmbedded([
            'fieldName' => $mapping['translatable']['translations'],
            'targetDocument' => $config['translation']['model'],
            'strategy' => 'set',
        ]);
    }
423520
public function getEmbedManyDbValue(EmbeddedPropMetadata $embeddedPropMeta, $embeds = null)
    {
        if (null === $embeds) {
            return;
        }
        if (!is_array($embeds) && !$embeds instanceof \Traversable) {
            throw new \InvalidArgumentException('Unable to traverse the embed collection');
        }

        $created = [];
        foreach ($embeds as $embed) {
            $created[] = $this->createEmbed($embeddedPropMeta, $embed);
        }
        return empty($created) ? null : $created;
    }
806756
protected function generateAssociationMappingPropertyDocBlock(array $associationMapping, ClassMetadataInfo $metadata)
    {
        $lines = array();
        $lines[] = $this->spaces . '/**';

        if ($associationMapping['type'] & ClassMetadataInfo::TO_MANY) {
            $lines[] = $this->spaces . ' * @var \Doctrine\Common\Collections\Collection';
        } else {
            $lines[] = $this->spaces . ' * @var \\' . ltrim($associationMapping['targetEntity'], '\\');
        }

        if ($this->generateAnnotations) {
            $lines[] = $this->spaces . ' *';

            if (isset($associationMapping['id']) && $associationMapping['id']) {
                $lines[] = $this->spaces . ' * @' . $this->annotationsPrefix . 'Id';

                if ($generatorType = $this->getIdGeneratorTypeString($metadata->generatorType)) {
                    $lines[] = $this->spaces . ' * @' . $this->annotationsPrefix . 'GeneratedValue(strategy="' . $generatorType . '")';
                }
            }

            $type = null;
            switch ($associationMapping['type']) {
                case ClassMetadataInfo::ONE_TO_ONE:
                    $type = 'OneToOne';
                    break;
                case ClassMetadataInfo::MANY_TO_ONE:
                    $type = 'ManyToOne';
                    break;
                case ClassMetadataInfo::ONE_TO_MANY:
                    $type = 'OneToMany';
                    break;
                case ClassMetadataInfo::MANY_TO_MANY:
                    $type = 'ManyToMany';
                    break;
            }
            $typeOptions = array();

            if (isset($associationMapping['targetEntity'])) {
                $typeOptions[] = 'targetEntity="' . $associationMapping['targetEntity'] . '"';
            }

            if (isset($associationMapping['inversedBy'])) {
                $typeOptions[] = 'inversedBy="' . $associationMapping['inversedBy'] . '"';
            }

            if (isset($associationMapping['mappedBy'])) {
                $typeOptions[] = 'mappedBy="' . $associationMapping['mappedBy'] . '"';
            }

            if ($associationMapping['cascade']) {
                $cascades = array();

                if ($associationMapping['isCascadePersist']) $cascades[] = '"persist"';
                if ($associationMapping['isCascadeRemove']) $cascades[] = '"remove"';
                if ($associationMapping['isCascadeDetach']) $cascades[] = '"detach"';
                if ($associationMapping['isCascadeMerge']) $cascades[] = '"merge"';
                if ($associationMapping['isCascadeRefresh']) $cascades[] = '"refresh"';

                if (count($cascades) === 5) {
                    $cascades = array('"all"');
                }

                $typeOptions[] = 'cascade={' . implode(',', $cascades) . '}';
            }

            if (isset($associationMapping['orphanRemoval']) && $associationMapping['orphanRemoval']) {
                $typeOptions[] = 'orphanRemoval=' . ($associationMapping['orphanRemoval'] ? 'true' : 'false');
            }

            if (isset($associationMapping['fetch']) && $associationMapping['fetch'] !== ClassMetadataInfo::FETCH_LAZY) {
                $fetchMap = array(
                    ClassMetadataInfo::FETCH_EXTRA_LAZY => 'EXTRA_LAZY',
                    ClassMetadataInfo::FETCH_EAGER      => 'EAGER',
                );

                $typeOptions[] = 'fetch="' . $fetchMap[$associationMapping['fetch']] . '"';
            }

            $lines[] = $this->spaces . ' * @' . $this->annotationsPrefix . '' . $type . '(' . implode(', ', $typeOptions) . ')';

            if (isset($associationMapping['joinColumns']) && $associationMapping['joinColumns']) {
                $lines[] = $this->spaces . ' * @' . $this->annotationsPrefix . 'JoinColumns({';

                $joinColumnsLines = array();

                foreach ($associationMapping['joinColumns'] as $joinColumn) {
                    if ($joinColumnAnnot = $this->generateJoinColumnAnnotation($joinColumn)) {
                        $joinColumnsLines[] = $this->spaces . ' *   ' . $joinColumnAnnot;
                    }
                }

                $lines[] = implode(",\n", $joinColumnsLines);
                $lines[] = $this->spaces . ' * })';
            }

            if (isset($associationMapping['joinTable']) && $associationMapping['joinTable']) {
                $joinTable = array();
                $joinTable[] = 'name="' . $associationMapping['joinTable']['name'] . '"';

                if (isset($associationMapping['joinTable']['schema'])) {
                    $joinTable[] = 'schema="' . $associationMapping['joinTable']['schema'] . '"';
                }

                $lines[] = $this->spaces . ' * @' . $this->annotationsPrefix . 'JoinTable(' . implode(', ', $joinTable) . ',';
                $lines[] = $this->spaces . ' *   joinColumns={';

                $joinColumnsLines = array();

                foreach ($associationMapping['joinTable']['joinColumns'] as $joinColumn) {
                    $joinColumnsLines[] = $this->spaces . ' *     ' . $this->generateJoinColumnAnnotation($joinColumn);
                }

                $lines[] = implode(",". PHP_EOL, $joinColumnsLines);
                $lines[] = $this->spaces . ' *   },';
                $lines[] = $this->spaces . ' *   inverseJoinColumns={';

                $inverseJoinColumnsLines = array();

                foreach ($associationMapping['joinTable']['inverseJoinColumns'] as $joinColumn) {
                    $inverseJoinColumnsLines[] = $this->spaces . ' *     ' . $this->generateJoinColumnAnnotation($joinColumn);
                }

                $lines[] = implode(",". PHP_EOL, $inverseJoinColumnsLines);
                $lines[] = $this->spaces . ' *   }';
                $lines[] = $this->spaces . ' * )';
            }

            if (isset($associationMapping['orderBy'])) {
                $lines[] = $this->spaces . ' * @' . $this->annotationsPrefix . 'OrderBy({';

                foreach ($associationMapping['orderBy'] as $name => $direction) {
                    $lines[] = $this->spaces . ' *     "' . $name . '"="' . $direction . '",';
                }

                $lines[count($lines) - 1] = substr($lines[count($lines) - 1], 0, strlen($lines[count($lines) - 1]) - 1);
                $lines[] = $this->spaces . ' * })';
            }
        }

        $lines[] = $this->spaces . ' */';

        return implode("\n", $lines);
    }
365483
public function setEntityProperty(?EntityProperty $entityProperty) {
		ArgUtils::assertTrue($entityProperty instanceof EmbeddedEntityProperty);
		
		parent::setEntityProperty($entityProperty);
	}
23259
public function removeEmbed($key, Embed $embed)
    {
        if (false === $this->isEmbedHasMany($key)) {
            return $this;
        }
        $this->touch();
        $collection = $this->hasManyEmbeds->get($key);
        $collection->remove($embed);
        $this->doDirtyCheck();
        return $this;
    }
502124
public function processClassMetadata(ClassMetadata $metadata, $property, $prefix)
    {
        if (in_array($metadata->getName(), $this->processedClasses)) {
            return;
        }

        $metadata->mapEmbedded([
            'fieldName'    => $property,
            'class'        => $this->embeddableMetadata->getName(),
            'columnPrefix' => empty($prefix) ? false : $prefix,
        ]);

        $metadata->inlineEmbeddable($property, $this->embeddableMetadata);

        $this->processedClasses[] = $metadata->getName();
    }
582177
public function inlineEmbeddable($property, ClassMetadataInfo $embeddable)
    {
        foreach ($embeddable->fieldMappings as $fieldMapping) {
            $fieldMapping['originalClass'] = isset($fieldMapping['originalClass'])
                ? $fieldMapping['originalClass']
                : $embeddable->name;
            $fieldMapping['declaredField'] = isset($fieldMapping['declaredField'])
                ? $property . '.' . $fieldMapping['declaredField']
                : $property;
            $fieldMapping['originalField'] = isset($fieldMapping['originalField'])
                ? $fieldMapping['originalField']
                : $fieldMapping['fieldName'];
            $fieldMapping['fieldName'] = $property . "." . $fieldMapping['fieldName'];

            if (! empty($this->embeddedClasses[$property]['columnPrefix'])) {
                $fieldMapping['columnName'] = $this->embeddedClasses[$property]['columnPrefix'] . $fieldMapping['columnName'];
            } elseif ($this->embeddedClasses[$property]['columnPrefix'] !== false) {
                $fieldMapping['columnName'] = $this->namingStrategy
                    ->embeddedFieldToColumnName(
                        $property,
                        $fieldMapping['columnName'],
                        $this->reflClass->name,
                        $embeddable->reflClass->name
                    );
            }

            $this->mapField($fieldMapping);
        }
    }
1265030
public function injectEntityManager(EntityManagerInterface $entityManager, ClassMetadata $classMetadata) : void
    {
        if ($entityManager !== self::$entityManager) {
            throw new RuntimeException(
                'Trying to use PersistentObject with different EntityManager instances. ' .
                'Was PersistentObject::setEntityManager() called?'
            );
        }

        $this->cm = $classMetadata;
    }
936344
private function createEmbed(EmbeddedPropMetadata $embeddedPropMeta, Embed $embed)
    {
        $embedMeta = $embeddedPropMeta->embedMeta;

        $obj = [];
        foreach ($embedMeta->getAttributes() as $key => $attrMeta) {
            $value = $this->getAttributeDbValue($attrMeta, $embed->get($key));
            if (null === $value) {
                continue;
            }
            $obj[$key] = $value;
        }
        foreach ($embedMeta->getEmbeds() as $key => $propMeta) {
            $value = (true === $propMeta->isOne()) ? $this->getEmbedOneDbValue($propMeta, $embed->get($key)) : $this->getEmbedManyDbValue($propMeta, $embed->get($key));
            if (null === $value) {
                continue;
            }
            $obj[$key] = $value;
        }
        return $obj;
    }
220292
protected function validateType($embedType)
    {
        $valid = ['one', 'many'];
        if (!in_array($embedType, $valid)) {
            throw MetadataException::invalidRelType($embedType, $valid);
        }
        return true;
    }
888429
private function prepareEmbeddedDocumentValue(PropertyMetadata $mapping, $document, $includeNestedCollections = false)
    {
        $result = [];
        $class  = $this->dm->getClassMetadata(get_class($document));

        foreach ($class->propertyMetadata as $embeddedMapping) {
            // Skip notSaved attributes
            if (!empty($embeddedMapping->notSaved)) {
                continue;
            }

            $rawValue = $class->getPropertyMetadata($embeddedMapping->name)->getValue($document);
            $value    = Type::getNull();

            if ($rawValue !== null) {
                switch ($embeddedMapping->association !== null ? $embeddedMapping->association : null) {
                    // @Attribute, @String, @Date, etc.
                    case null:
                        $value = $embeddedMapping->getType()->convertToDatabaseValue($rawValue);

                        break;
                    case PropertyMetadata::ASSOCIATION_TYPE_EMBED_ONE:
                        $value = $this->prepareEmbeddedDocumentValue($embeddedMapping, $rawValue, $includeNestedCollections);

                        break;
                    case PropertyMetadata::ASSOCIATION_TYPE_REFERENCE_ONE:
                        $value = $this->prepareReferencedDocumentValue($embeddedMapping, $rawValue);

                        break;
                    case PropertyMetadata::ASSOCIATION_TYPE_EMBED_MANY:
                    case PropertyMetadata::ASSOCIATION_TYPE_REFERENCE_MANY:
                        // Skip PersistentCollections already scheduled for deletion
                        if (!$includeNestedCollections && $rawValue instanceof PersistentCollectionInterface
                            && $this->uow->isCollectionScheduledForDeletion($rawValue)) {
                            break;
                        }

                        $value = $this->prepareAssociatedCollectionValue($embeddedMapping, $rawValue, $includeNestedCollections);

                        break;
                    default:
                        throw new \UnexpectedValueException('Unsupported mapping association: ' . $embeddedMapping->association);
                }
            }

            // Omit non-nullable attributes that would have a null value
            if ($value === Type::getNull() && !$embeddedMapping->nullable) {
                continue;
            }

            $result[$embeddedMapping->name] = $value;
        }

        /* Add a discriminator value if the embedded document is not mapped
         * explicitly to a targetDocument class.
         */
        if ($mapping->targetDocument === null) {
            $discriminatorAttribute = $mapping->discriminatorAttribute;
            $discriminatorValue     = $mapping->discriminatorMap !== null
                ? array_search($class->name, $mapping->discriminatorMap)
                : $class->name;

            /* If the discriminator value was not found in the map, use the full
             * class name. In the future, it may be preferable to throw an
             * exception here (perhaps based on some strictness option).
             *
             * @see DocumentManager::createDBRef()
             */
            if ($discriminatorValue === false) {
                $discriminatorValue = $class->name;
            }

            $result[$discriminatorAttribute] = $discriminatorValue;
        }

        /* If the class has a discriminator (attribute and value), use it. A child
         * class that is not defined in the discriminator map may only have a
         * discriminator attribute and no value, so default to the full class name.
         */
        if ($class->discriminatorAttribute !== null) {
            $result[$class->discriminatorAttribute] = $class->discriminatorValue !== null
                ? $class->discriminatorValue
                : $class->name;
        }

        return TypeFactory::getType(Type::MAP)->convertToDatabaseValue($result);
    }