Skip to content

Commit

Permalink
Merge pull request #2444 from malarzm/type-autoconfigure-final-touche…
Browse files Browse the repository at this point in the history
…s-mm

Final touches for type autoconfiguration
  • Loading branch information
malarzm authored May 8, 2022
2 parents df1d775 + b274e9f commit cdb60e2
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 17 deletions.
12 changes: 10 additions & 2 deletions docs/en/reference/basic-mapping.rst
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,9 @@ This list explains some of the less obvious mapping types:
PHP Types Mapping
_________________

.. note::
Doctrine will skip type autoconfiguration if settings are provided explicitly.

Since version 2.4 Doctrine can determine usable defaults from property types
on document classes. Doctrine will map PHP types to ``type`` attribute as
follows:
Expand All @@ -215,11 +218,16 @@ follows:
- ``int``: ``int``
- ``string``: ``string``

Doctrine will also autoconfigure any backed ``enum`` it encounters: ``type``
Doctrine can also autoconfigure any backed ``enum`` it encounters: ``type``
will be set to ``string`` or ``int``, depending on the enum's backing type,
and ``enumType`` to the enum's |FQCN|.

Please note that at this time, due to backward compatibility reasons, nullable type does not imply `nullable` mapping.
.. note::
Nullable type does not imply ``nullable`` mapping option. You need to manually
set ``nullable=true`` to have ``null`` values saved to the database.

Additionally Doctrine can determine ``collectionClass`` for ``ReferenceMany`` and
``EmbedMany`` collections from property's type.

Property Mapping
----------------
Expand Down
28 changes: 13 additions & 15 deletions lib/Doctrine/ODM/MongoDB/Mapping/ClassMetadata.php
Original file line number Diff line number Diff line change
Expand Up @@ -1563,6 +1563,7 @@ public function mapManyEmbedded(array $mapping): void
{
$mapping['embedded'] = true;
$mapping['type'] = self::MANY;

$this->mapField($mapping);
}

Expand All @@ -1588,6 +1589,7 @@ public function mapManyReference(array $mapping): void
{
$mapping['reference'] = true;
$mapping['type'] = self::MANY;

$this->mapField($mapping);
}

Expand Down Expand Up @@ -2120,7 +2122,7 @@ public function getAssociationTargetClass($assocName): ?string
throw new InvalidArgumentException("Association name expected, '" . $assocName . "' is not an association.");
}

return $this->associationMappings[$assocName]['targetDocument'];
return $this->associationMappings[$assocName]['targetDocument'] ?? null;
}

/**
Expand Down Expand Up @@ -2170,6 +2172,14 @@ public function mapField(array $mapping): array
$mapping['fieldName'] = $mapping['name'];
}

if ($this->isTypedProperty($mapping['fieldName'])) {
$mapping = $this->validateAndCompleteTypedFieldMapping($mapping);

if (isset($mapping['type']) && $mapping['type'] === self::MANY) {
$mapping = $this->validateAndCompleteTypedManyAssociationMapping($mapping);
}
}

if (! isset($mapping['fieldName']) || ! is_string($mapping['fieldName'])) {
throw MappingException::missingFieldName($this->name);
}
Expand Down Expand Up @@ -2242,14 +2252,6 @@ public function mapField(array $mapping): array
unset($this->generatorOptions['type']);
}

if ($this->isTypedProperty($mapping['fieldName'])) {
$mapping = $this->validateAndCompleteTypedFieldMapping($mapping);

if (isset($mapping['type']) && ($mapping['type'] === self::ONE || $mapping['type'] === self::MANY)) {
$mapping = $this->validateAndCompleteTypedAssociationMapping($mapping);
}
}

if (! isset($mapping['type'])) {
// Default to string
$mapping['type'] = Type::STRING;
Expand Down Expand Up @@ -2653,19 +2655,15 @@ private function validateAndCompleteTypedFieldMapping(array $mapping): array
*
* @return FieldMappingConfig
*/
private function validateAndCompleteTypedAssociationMapping(array $mapping): array
private function validateAndCompleteTypedManyAssociationMapping(array $mapping): array
{
$type = $this->reflClass->getProperty($mapping['fieldName'])->getType();

if (! $type instanceof ReflectionNamedType) {
return $mapping;
}

if (
! isset($mapping['collectionClass'])
&& $mapping['type'] === self::MANY
&& class_exists($type->getName())
) {
if (! isset($mapping['collectionClass']) && class_exists($type->getName())) {
$mapping['collectionClass'] = $type->getName();
}

Expand Down

0 comments on commit cdb60e2

Please sign in to comment.