Odświeżam sobie trochę Symfony i robię taki mały projekcik. Chciałbym zapisywać sobie kolekcję ValueObject do bazy w formacie JSON.
Jeden ze sposobów jaki mi przyszedł do głowy to użycie Custom Types, ale przypuszczam, że to nie jest potrzebne.
Moje Entity wygląda tak:
class App
{
public function __construct(
private AppId $id,
private string $name,
private UserRoleCollection $userRoles
) {
}
...
}
Mapowanie w xml
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="https://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://doctrine-project.org/schemas/orm/doctrine-mapping
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity name="App\Domain\App" table="app">
<id name="id" column="id" type="AppId" />
<field name="name" length="40" />
<field name="userRoles" type="json" column="user_roles"/>
</entity>
</doctrine-mapping>
Problematyczny obiekt UserRoleCollection wygląda tak:
<?php
declare(strict_types=1);
namespace App\Domain\ValueObject;
use ArrayIterator;
use Assert\Assertion;
use IteratorAggregate;
use JsonSerializable;
use Traversable;
final class UserRoleCollection implements IteratorAggregate, JsonSerializable
{
private array $items;
/**
* @param UserRole[] $items
*/
public function __construct(array $items = [])
{
Assertion::allIsInstanceOf($items, UserRole::class);
$this->items = [];
foreach ($items as $item) {
$this->addItem($item);
}
}
public function items(): array
{
return $this->items;
}
(...)
public function jsonSerialize()
{
return $this->items;
}
}
Z UserRoleCollection chciałbym dojść do takiego stanu aby działało to jak z mapowanie typu "object" czyli pełen automat przy zapisie i odczycie z bazy, z tą różnicą że chcę w bazie mieć JSON a nie obiekt serializowany przez PHP. UserRolesCollection to kolekcja obiektów UserRole - po dodaniu interfejsu \JsonSerializable zapis już działa, ale niestety nie działa wczytanie obiektu z bazy. Problem polega na tym, że "items" to tablica obiektów i doctrine przy deserializacji próbuje wrzucić do niej zwykłe wartości tekstowe.
Pytanie więc czy jakoś w Symfony mogę Doctrine zmusić do serializowanie/deserializowania mojego obiektu np. przy użyciu JMS Serializer (albo jest jakiś inny sprytny sposób), czy też dla każdej takie kolekcji muszę rejestrować Custom Type i tam ręcznie wywoływać JMS Serializer?