gpt4 book ai didi

symfony - API 平台 - onPreSerialize with MediaObject URI Resolver in normalization group

转载 作者:行者123 更新时间:2023-12-04 01:01:03 24 4
gpt4 key购买 nike

我有一个 MediaObject 作为规范化上下文组“模块”中的子资源公开:

/**
* @ApiResource(
* attributes={"access_control"="is_granted('ROLE_ADMIN')"},
* collectionOperations={
* "get",
* "post",
* "allData"={
* "method"="GET",
* "path"="/appdata",
* "normalization_context"={"groups"={"modules"}},
* "access_control"="is_granted('IS_AUTHENTICATED_ANONYMOUSLY')"
* }
* }
* )
* @ORM\Entity(repositoryClass="App\Repository\LearningModuleRepository")
* @UniqueEntity("identifier")
*
*/
class LearningModule
/**
* @ORM\Entity(
* repositoryClass="App\Repository\MediaObjectRepository"
* )
* @ApiResource(
* iri="http://schema.org/MediaObject",
* normalizationContext={
* "groups"={"media_object_read"},
* },
* attributes={"access_control"="is_granted('ROLE_ADMIN')"},
* collectionOperations={
* "post"={
* "controller"=CreateMediaObject::class,
* "deserialize"=false,
* "validation_groups"={"Default", "media_object_create"},
* "swagger_context"={
* "consumes"={
* "multipart/form-data",
* },
* "parameters"={
* {
* "in"="formData",
* "name"="file",
* "type"="file",
* "description"="The file to upload",
* },
* },
* },
* },
* "get",
* },
* itemOperations={
* "get",
* "delete"
* },
* )
* @Vich\Uploadable
*/
class MediaObject


/**
* @var string|null
*
* @ApiProperty(iri="http://schema.org/contentUrl")
* @Groups({"media_object_read", "modules"})
*/
public $contentUrl;

/**
* @var string|null
* @Groups({"modules"})
* @ORM\Column(nullable=true)
*/
public $filePath;

当通过规范化组公开时,我只得到 filePath 而不是 contentUrl。我假设问题与 official docs 中概述的 ContentUrlSubscriber 有关。 :

    public static function getSubscribedEvents(): array
{
return [
KernelEvents::VIEW => ['onPreSerialize', EventPriorities::PRE_SERIALIZE],
];
}

public function onPreSerialize(GetResponseForControllerResultEvent $event): void
{
$controllerResult = $event->getControllerResult();
$request = $event->getRequest();

if ($controllerResult instanceof Response || !$request->attributes->getBoolean('_api_respond', true)) {
return;
}

if (!($attributes = RequestAttributesExtractor::extractAttributes($request)) || !\is_a($attributes['resource_class'], MediaObject::class, true)) {
return;
}

$mediaObjects = $controllerResult;

if (!is_iterable($mediaObjects)) {
$mediaObjects = [$mediaObjects];
}

foreach ($mediaObjects as $mediaObject) {
if (!$mediaObject instanceof MediaObject) {
continue;
}

$mediaObject->contentUrl = $this->storage->resolveUri($mediaObject, 'file');
}
}

在这种情况下,有人知道如何处理预序列化吗?

谢谢

最佳答案

我找到了解决这个问题的办法:

  • PRE_SERIALIZE 的回调被中止,因为 LearningModule 对象(不是 MediaObject)触发了序列化($attributes['resource_class'] === LearningModule)。

  • 要克服此限制,应按如下方式使用修饰规范化器:

<?php

namespace App\Serializer;

use App\Entity\MediaObject;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
use Symfony\Component\Serializer\SerializerAwareInterface;
use Symfony\Component\Serializer\SerializerInterface;
use Vich\UploaderBundle\Storage\StorageInterface;

final class MediaObjectContentUrlNormalizer implements NormalizerInterface, DenormalizerInterface, SerializerAwareInterface
{
private $decorated;
private $storage;

public function __construct(NormalizerInterface $decorated, StorageInterface $storage)
{
if (!$decorated instanceof DenormalizerInterface) {
throw new \InvalidArgumentException(sprintf('The decorated normalizer must implement the %s.', DenormalizerInterface::class));
}

$this->decorated = $decorated;
$this->storage = $storage;
}

public function supportsNormalization($data, $format = null)
{
return $this->decorated->supportsNormalization($data, $format);
}

public function normalize($object, $format = null, array $context = [])
{
$data = $this->decorated->normalize($object, $format, $context);
if ($object instanceof MediaObject) {
$data['contentUrl'] = $this->storage->resolveUri( $object, 'file');
}

return $data;
}

public function supportsDenormalization($data, $type, $format = null)
{
return $this->decorated->supportsDenormalization($data, $type, $format);
}

public function denormalize($data, $class, $format = null, array $context = [])
{
return $this->decorated->denormalize($data, $class, $format, $context);
}

public function setSerializer(SerializerInterface $serializer)
{
if($this->decorated instanceof SerializerAwareInterface) {
$this->decorated->setSerializer($serializer);
}
}
}

实现细节可以在这里找到: https://api-platform.com/docs/core/serialization/#decorating-a-serializer-and-adding-extra-data

关于symfony - API 平台 - onPreSerialize with MediaObject URI Resolver in normalization group,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58318524/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com