Сериализатор JMS: динамическое изменение имени виртуального свойства во время выполнения
Я использую JMS Serializer Bundle и Symfony2. Я использую VirtualProperties. в настоящее время я устанавливаю имя свойства с помощью аннотации SerializedName.
/**
* @JMS\VirtualProperty()
* @JMS\SerializedName("SOME_NAME")
*/
public function getSomething()
{
return $this->something
}
Можно ли динамически установить сериализованное имя внутри функции? Или можно динамически влиять на имя, используя события сериализации Post/Pre?
Спасибо!
2 ответа
Я не думаю, что вы можете сделать это напрямую, но вы могли бы сделать нечто подобное, имея несколько виртуальных свойств, по одному для каждого возможного имени. Если имя не относится к конкретной сущности, попросите метод вернуть значение null и отключите сериализацию null в конфигурации JMS.
В тот момент, когда вы собираетесь сериализовать объект, сделайте следующее:
$this->serializer = SerializerBuilder::create()->setPropertyNamingStrategy(new IdenticalPropertyNamingStrategy())->build();
$json = $this->serializer->serialize($object, 'json');
dump($json);
Сущность
/**
* @JMS\VirtualProperty("something", exp="context", options={
* @JMS\Expose,
* })
*/
class SomeEntity
{
}
Слушатель событий
abstract class AbstractEntitySubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
[
'event' => Events::POST_SERIALIZE,
'method' => 'onPostSerialize',
'class' => static::getClassName(),
'format' => JsonEncoder::FORMAT,
'priority' => 0,
],
];
}
public function onPostSerialize(ObjectEvent $event): void
{
foreach ($this->getMethodNames() as $methodName) {
$visitor = $event->getVisitor();
$metadata = new VirtualPropertyMetadata(static::getClassName(), $methodName);
if ($visitor->hasData($metadata->name)) {
$value = $this->{$methodName}($event->getObject());
$visitor->visitProperty(
new StaticPropertyMetadata(static::getClassName(), $metadata->name, $value),
$value
);
}
}
}
abstract protected static function getClassName(): string;
abstract protected function getMethodNames(): array;
}
...
class SomeEntitySubscriber extends AbstractEntitySubscriber
{
protected static function getClassName(): string
{
return SomeEntity::class;
}
protected function getMethodNames(): array
{
return ['getSomething'];
}
protected function getSomething(SomeEntity $someEntity)
{
return 'some text';
}
}