Skip to content

Commit d446495

Browse files
committed
Add documentation for custom type covering value object
1 parent 26e1bb5 commit d446495

File tree

1 file changed

+108
-2
lines changed

1 file changed

+108
-2
lines changed

docs/en/reference/custom-mapping-types.rst

Lines changed: 108 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ In order to create a new mapping type you need to subclass
99
``Doctrine\ODM\MongoDB\Types\Type`` and implement/override
1010
the methods.
1111

12+
Date Example: Mapping DateTimeImmutable with Timezone
13+
-----------------------------------------------------
14+
1215
The following example defines a custom type that stores ``DateTimeInterface``
1316
instances as an embedded document containing a BSON date and accompanying
1417
timezone string. Those same embedded documents are then be translated back into
@@ -115,5 +118,108 @@ specify a unique name for the mapping type and map that to the corresponding
115118
116119
<field field-name="field" type="date_with_timezone" />
117120
118-
.. |FQCN| raw:: html
119-
<abbr title="Fully-Qualified Class Name">FQCN</abbr>
121+
Custom Type Example: Mapping a UUID Class
122+
========================================
123+
124+
You can create a custom mapping type for your own value objects or classes. For
125+
example, to map a UUID value object using the `ramsey/uuid library`_, you can
126+
implement a type that converts between your class and the MongoDB binary format.
127+
128+
This approach works for any custom class—just adapt the conversion logic to your needs.
129+
130+
Example Implementation (using Ramsey\Uuid\UuidInterface)::
131+
132+
133+
.. code-block:: php
134+
<?php
135+
136+
namespace My\Project\Types;
137+
138+
use Doctrine\ODM\MongoDB\Types\ClosureToPHP;
139+
use Doctrine\ODM\MongoDB\Types\Type;
140+
use InvalidArgumentException;
141+
use MongoDB\BSON\Binary;
142+
use Ramsey\Uuid\Uuid;
143+
use Ramsey\Uuid\UuidInterface;
144+
145+
final class UuidType extends Type
146+
{
147+
use ClosureToPHP;
148+
149+
public function convertToPHPValue(mixed $value): ?Uuid
150+
{
151+
if (null === $value) {
152+
return null;
153+
}
154+
155+
if ($value instanceof Uuid) {
156+
return $value;
157+
}
158+
159+
if ($value instanceof Binary) {
160+
return Uuid::fromBytes($value->getData());
161+
}
162+
163+
if (is_string($value) && Uuid::isValid($value)) {
164+
return Uuid::fromString($value);
165+
}
166+
167+
throw new InvalidArgumentException(
168+
sprintf(
169+
'Could not convert database value "%s" from "%s" to %s',
170+
$value,
171+
get_debug_type($value),
172+
UuidInterface::class
173+
)
174+
);
175+
}
176+
177+
public function convertToDatabaseValue(mixed $value): ?Binary
178+
{
179+
if (null === $value || [] === $value) {
180+
return null;
181+
}
182+
183+
if ($value instanceof Binary) {
184+
return $value;
185+
}
186+
187+
if (is_string($value) && Uuid::isValid($value)) {
188+
$value = Uuid::fromString($value)->getBytes();
189+
}
190+
191+
if ($value instanceof Uuid) {
192+
return new Binary($value->getBytes(), Binary::TYPE_UUID);
193+
}
194+
195+
throw new InvalidArgumentException(
196+
sprintf(
197+
'Could not convert database value "%s" from "%s" to %s',
198+
$value,
199+
get_debug_type($value),
200+
Binary::class
201+
)
202+
);
203+
}
204+
}
205+
206+
Usage Example::
207+
208+
.. code-block:: php
209+
210+
#[Field(type: Uuid::class)]
211+
public Uuid $id;
212+
213+
Register the type in your bootstrap code::
214+
215+
.. code-block:: php
216+
217+
Type::addType(Ramsey\Uuid\Uuid::class, My\Project\Types\UuidType::class);
218+
219+
.. note::
220+
The type name should match the support class name (e.g., ``uuid`` for ``UuidType``) to enable automatic association with the field type.
221+
222+
This pattern can be adapted for any custom class—just implement the conversion logic for your value object.
223+
224+
.. |FQCN| raw:: html <abbr title="Fully-Qualified Class Name">FQCN</abbr>
225+
.. _`ramsey/uuid library`: https://github.com/ramsey/uuid

0 commit comments

Comments
 (0)