Skip to content

Commit a3d8acf

Browse files
committed
Convert the value of the 'version' field using its known type
1 parent afb565e commit a3d8acf

File tree

2 files changed

+92
-4
lines changed

2 files changed

+92
-4
lines changed

lib/Doctrine/ODM/MongoDB/Persisters/DocumentPersister.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ public function executeInserts(array $options = []): void
218218
$this->class->reflFields[$this->class->versionField]->setValue($document, $nextVersion);
219219
}
220220

221-
$data[$versionMapping['name']] = $type->convertPHPToDatabaseValue($nextVersion);
221+
$data[$versionMapping['name']] = $type->convertToDatabaseValue($nextVersion);
222222
}
223223

224224
$inserts[] = $data;
@@ -296,7 +296,7 @@ private function executeUpsert(object $document, array $options): void
296296
$this->class->reflFields[$this->class->versionField]->setValue($document, $nextVersion);
297297
}
298298

299-
$data['$set'][$versionMapping['name']] = $type->convertPHPToDatabaseValue($nextVersion);
299+
$data['$set'][$versionMapping['name']] = $type->convertToDatabaseValue($nextVersion);
300300
}
301301

302302
foreach (array_keys($criteria) as $field) {
@@ -377,8 +377,8 @@ public function update(object $document, array $options = []): void
377377
$type = Type::getType($versionMapping['type']);
378378
assert($type instanceof Versionable);
379379
$nextVersion = $type->getNextVersion($currentVersion);
380-
$update['$set'][$versionMapping['name']] = Type::convertPHPToDatabaseValue($nextVersion);
381-
$query[$versionMapping['name']] = Type::convertPHPToDatabaseValue($currentVersion);
380+
$update['$set'][$versionMapping['name']] = $type->convertToDatabaseValue($nextVersion);
381+
$query[$versionMapping['name']] = $type->convertToDatabaseValue($currentVersion);
382382
}
383383

384384
if (! empty($update)) {
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Doctrine\ODM\MongoDB\Tests\Functional\Ticket;
6+
7+
use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;
8+
use Doctrine\ODM\MongoDB\Tests\BaseTestCase;
9+
use Doctrine\ODM\MongoDB\Types\Type;
10+
use Doctrine\ODM\MongoDB\Types\Versionable;
11+
use MongoDB\BSON\Binary;
12+
use PHPUnit\Framework\Attributes\BackupGlobals;
13+
14+
use function assert;
15+
use function is_int;
16+
17+
#[BackupGlobals(true)]
18+
class GH2789Test extends BaseTestCase
19+
{
20+
public function testVersionWithCustomType(): void
21+
{
22+
Type::addType(GH2789CustomType::class, GH2789CustomType::class);
23+
$doc = new GH2789VersionedUuid('original message');
24+
25+
$this->dm->persist($doc);
26+
$this->dm->flush();
27+
28+
$documents = $this->dm->getDocumentCollection(GH2789VersionedUuid::class)->find()->toArray();
29+
self::assertCount(1, $documents);
30+
self::assertEquals(new Binary('1', 142), $documents[0]['version'], 'The version field should be stored using the custom type');
31+
32+
$doc->message = 'new message';
33+
$this->dm->persist($doc);
34+
$this->dm->flush();
35+
36+
$documents = $this->dm->getDocumentCollection(GH2789VersionedUuid::class)->find()->toArray();
37+
self::assertCount(1, $documents);
38+
self::assertEquals(new Binary('2', 142), $documents[0]['version'], 'The version field should be incremented and stored using the custom type');
39+
}
40+
}
41+
42+
#[ODM\Document(collection: 'gh2789_versioned_uuid')]
43+
class GH2789VersionedUuid
44+
{
45+
#[ODM\Id]
46+
public string $id;
47+
48+
#[ODM\Version]
49+
#[ODM\Field(type: GH2789CustomType::class)]
50+
public int $version;
51+
52+
public function __construct(
53+
#[ODM\Field(type: 'string')]
54+
public string $message,
55+
) {
56+
}
57+
}
58+
59+
/**
60+
* Custom type that stores an integer as a MongoDB Binary subtype 142.
61+
*/
62+
class GH2789CustomType extends Type implements Versionable
63+
{
64+
public function convertToPHPValue($value): int
65+
{
66+
assert($value instanceof Binary);
67+
68+
return (int) $value->getData();
69+
}
70+
71+
public function convertToDatabaseValue($value): Binary
72+
{
73+
assert(is_int($value));
74+
75+
return new Binary((string) $value, 142);
76+
}
77+
78+
public function getNextVersion($current): int
79+
{
80+
if ($current === null) {
81+
return 1;
82+
}
83+
84+
assert(is_int($current));
85+
86+
return $current + 1;
87+
}
88+
}

0 commit comments

Comments
 (0)