Skip to content

Commit

Permalink
Fix prepareQueryOrNewObj with object values
Browse files Browse the repository at this point in the history
In convertToDatabaseValue, fallback to Type::convertPHPToDatabaseValue
if the field doesn't have a mapping.
  • Loading branch information
alanpoulain committed May 29, 2020
1 parent e2d0595 commit 3fb3ba0
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 7 deletions.
22 changes: 15 additions & 7 deletions lib/Doctrine/ODM/MongoDB/Persisters/DocumentPersister.php
Original file line number Diff line number Diff line change
Expand Up @@ -1012,10 +1012,7 @@ public function prepareQueryOrNewObj(array $query, bool $isNewObj = false) : arr

$preparedQueryElements = $this->prepareQueryElement((string) $key, $value, null, true, $isNewObj);
foreach ($preparedQueryElements as [$preparedKey, $preparedValue]) {
$preparedValue = Type::convertPHPToDatabaseValue($preparedValue);
if ($this->class->hasField($key)) {
$preparedValue = $this->convertToDatabaseValue($key, $preparedValue);
}
$preparedValue = $this->convertToDatabaseValue($key, $preparedValue);
$preparedQuery[$preparedKey] = $preparedValue;
}
}
Expand All @@ -1024,16 +1021,23 @@ public function prepareQueryOrNewObj(array $query, bool $isNewObj = false) : arr
}

/**
* Converts a single value to its database representation based on the mapping type
* Converts a single value to its database representation based on the mapping type if possible.
*
* @param mixed $value
*
* @return mixed
*/
private function convertToDatabaseValue(string $fieldName, $value)
{
$mapping = $this->class->fieldMappings[$fieldName];
$typeName = $mapping['type'];
$mapping = [];
$typeName = '';
$dbValue = false;
if ($this->class->hasField($fieldName)) {
$mapping = $this->class->fieldMappings[$fieldName];
$typeName = $mapping['type'];
} else {
$dbValue = Type::convertPHPToDatabaseValue($value);
}

if (is_array($value)) {
foreach ($value as $k => $v) {
Expand All @@ -1043,6 +1047,10 @@ private function convertToDatabaseValue(string $fieldName, $value)
return $value;
}

if ($dbValue !== false) {
return $dbValue;
}

if (! empty($mapping['reference']) || ! empty($mapping['embedded'])) {
return $value;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Doctrine\ODM\MongoDB\Tests\Functional;

use Closure;
use DateTime;
use Doctrine\ODM\MongoDB\DocumentManager;
use Doctrine\ODM\MongoDB\LockException;
use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;
Expand All @@ -15,6 +16,7 @@
use Generator;
use InvalidArgumentException;
use MongoDB\BSON\ObjectId;
use MongoDB\BSON\UTCDateTime;
use MongoDB\Collection;
use ReflectionProperty;
use function get_class;
Expand Down Expand Up @@ -461,6 +463,43 @@ public function testPrepareQueryOrNewObjWithDBRefReferenceToTargetDocumentWithHa
$this->assertEquals($expected, $documentPersister->prepareQueryOrNewObj($value));
}

/**
* @dataProvider queryProviderForComplexRefWithObjectValue
*/
public function testPrepareQueryOrNewObjWithComplexRefToTargetDocumentFieldWithObjectValue(array $expected, array $query)
{
$class = DocumentPersisterTestDocument::class;
$documentPersister = $this->uow->getDocumentPersister($class);

$this->assertEquals(
$expected,
$documentPersister->prepareQueryOrNewObj($query)
);
}

public static function queryProviderForComplexRefWithObjectValue() : Generator
{
yield 'Direct comparison' => [
'expected' => ['complexRef.date' => new UTCDateTime('1590710400000')],
'query' => ['complexRef.date' => new DateTime('2020-05-29')],
];

yield 'Operator with single value' => [
'expected' => ['complexRef.date' => ['$ne' => new UTCDateTime('1590710400000')]],
'query' => ['complexRef.date' => ['$ne' => new DateTime('2020-05-29')]],
];

yield 'Operator with multiple values' => [
'expected' => ['complexRef.date' => ['$in' => [new UTCDateTime('1590710400000'), new UTCDateTime('1590796800000')]]],
'query' => ['complexRef.date' => ['$in' => [new DateTime('2020-05-29'), new DateTime('2020-05-30')]]],
];

yield 'Nested operator' => [
'expected' => ['complexRef.date' => ['$not' => ['$in' => [new UTCDateTime('1590710400000'), new UTCDateTime('1590796800000')]]]],
'query' => ['complexRef.date' => ['$not' => ['$in' => [new DateTime('2020-05-29'), new DateTime('2020-05-30')]]]],
];
}

public function testPrepareQueryOrNewObjWithEmbeddedReferenceToTargetDocumentWithNormalIdType()
{
$class = DocumentPersisterTestHashIdDocument::class;
Expand Down

0 comments on commit 3fb3ba0

Please sign in to comment.