diff --git a/lib/Doctrine/ODM/MongoDB/Persisters/DocumentPersister.php b/lib/Doctrine/ODM/MongoDB/Persisters/DocumentPersister.php index 55352a1f70..3a52b19095 100644 --- a/lib/Doctrine/ODM/MongoDB/Persisters/DocumentPersister.php +++ b/lib/Doctrine/ODM/MongoDB/Persisters/DocumentPersister.php @@ -4,6 +4,7 @@ namespace Doctrine\ODM\MongoDB\Persisters; +use BackedEnum; use BadMethodCallException; use Doctrine\ODM\MongoDB\Aggregation\Stage\Sort; use Doctrine\ODM\MongoDB\DocumentManager; @@ -1128,6 +1129,10 @@ private function convertToDatabaseValue(string $fieldName, $value) } if (! $this->class->hasField($fieldName)) { + if ($value instanceof BackedEnum) { + $value = $value->value; + } + return Type::convertPHPToDatabaseValue($value); } @@ -1144,6 +1149,10 @@ private function convertToDatabaseValue(string $fieldName, $value) ); } + if ($value instanceof BackedEnum && isset($mapping['enumType'])) { + $value = $value->value; + } + if (in_array($typeName, ['collection', 'hash'])) { return $value; } diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/EnumTest.php b/tests/Doctrine/ODM/MongoDB/Tests/Functional/EnumTest.php index 3d701efb66..d3a0fd8fde 100644 --- a/tests/Doctrine/ODM/MongoDB/Tests/Functional/EnumTest.php +++ b/tests/Doctrine/ODM/MongoDB/Tests/Functional/EnumTest.php @@ -9,6 +9,7 @@ use Doctrine\Persistence\Mapping\Driver\MappingDriver; use Documents81\Card; use Documents81\Suit; +use Error; use MongoDB\BSON\ObjectId; use ValueError; @@ -49,6 +50,53 @@ public function testLoadingInvalidBackingValueThrowsError(): void $this->dm->getRepository(Card::class)->findOneBy([]); } + public function testQueryWithMappedField(): void + { + $qb = $this->dm->createQueryBuilder(Card::class) + ->field('suit')->equals(Suit::Spades) + ->field('nullableSuit')->in([Suit::Hearts, Suit::Diamonds]); + + $this->assertSame([ + 'suit' => 'S', + 'nullableSuit' => [ + '$in' => ['H', 'D'], + ], + ], $qb->getQuery()->debug('query')); + } + + public function testQueryWithMappedFieldAndEnumValue(): void + { + $qb = $this->dm->createQueryBuilder(Card::class) + ->field('suit')->equals('S') // Suit::Spades->value + ->field('nullableSuit')->in(['H', 'D']); + + $this->assertSame([ + 'suit' => 'S', + 'nullableSuit' => [ + '$in' => ['H', 'D'], + ], + ], $qb->getQuery()->debug('query')); + } + + public function testQueryWithNotMappedField(): void + { + $qb = $this->dm->createQueryBuilder(Card::class) + ->field('nonExisting')->equals(Suit::Clubs) + ->field('nonExistingArray')->equals([Suit::Clubs, Suit::Hearts]); + + $this->assertSame(['nonExisting' => 'C', 'nonExistingArray' => ['C', 'H']], $qb->getQuery()->debug('query')); + } + + public function testQueryWithMappedNonEnumFieldIsPassedToTypeDirectly(): void + { + $this->expectException(Error::class); + $this->expectExceptionMessage(sprintf('Object of class %s could not be converted to string', Suit::class)); + + $qb = $this->dm->createQueryBuilder(Card::class)->field('_id')->equals(Suit::Clubs); + + $this->assertSame(['_id' => 'C'], $qb->getQuery()->debug('query')); + } + protected function createMetadataDriverImpl(): MappingDriver { return AttributeDriver::create(__DIR__ . '/../../../Documents');