如何在 FOSRestBundle/JMS 序列化程序中更改字段的值


How to change value of field in FOSRestBundle/JMS Serializer?

我在实体中有"图像"字段。但取决于动作,我想显示的不是原始图像,而是图像的预览(我在LiipImagineBundle中制作)。我能想象到的一个解决方案:

public function cgetAction(Request $request)
{
    $events = $this->container->get('gc.event_manager')->getEvents();
    foreach ($events as &$event) {
        $previewURL = $this->getPreview($event->getPhoto());
        $event->setPhoto($previewURL);
    }
    $event = false;
    return array(
        'events' => $events,
    );
}

但我不喜欢它,因为如果一个实体有深度子实体,代码将非常混乱。

如何正确操作?

在使用 LiipImagine 和 FOSRest 时想要通过 API 返回绝对 url 的常见问题

将EE''TYSBundle更改为您自己的代码,代码取自 https://github.com/EE/TellYourStoryBundle/tree/develop

JMS系列处理程序服务与注入的缓存管理器,以获取正确的前缀

ee_tys.serializer.filename_handler:
    class: EE'TYSBundle'Handler'FilenameHandler
    arguments:
        - "@liip_imagine.cache.manager"
    tags:
        - { name: 'jms_serializer.handler', type: Filename, format: json}

自定义文件名类型的处理程序

EE''TYSBundle''Handler''FilenameHandler.php

<?php
namespace EE'TYSBundle'Handler;
use EE'TYSBundle'Entity'Filename;
use JMS'Serializer'GraphNavigator;
use JMS'Serializer'Handler'SubscribingHandlerInterface;
use JMS'Serializer'VisitorInterface;
use Liip'ImagineBundle'Imagine'Cache'CacheManager;
class FilenameHandler implements SubscribingHandlerInterface
{
    function __construct(CacheManager $manager)
    {
        $this->manager = $manager;
    }

    public static function getSubscribingMethods()
    {
        return array(
            array(
                'direction' => GraphNavigator::DIRECTION_SERIALIZATION,
                'format' => 'json',
                'type' => 'Filename',
                'method' => 'serializeFilenameToJson',
            ),
        );
    }
    public function serializeFilenameToJson(VisitorInterface $visitor, Filename $filename, array $type)
    {
        // `tile` is a name of Imagine filter you want to apply
        return $this->manager->getBrowserPath($filename, 'tile', true);
    }
}

EE''TYSBundle''Entity''Filename

<?php
namespace EE'TYSBundle'Entity;
/**
 * Class Filename
 * @package EE'TYSBundle'Entity
 */
class Filename {
    /**
     * @var string
     */
    public $name;
    /**
     * @var string
     */
    public $extension;
    public function __construct($filename)
    {
        $parts = explode(".", $filename);
        $this->setName($parts[0]);
        $this->setExtension($parts[1]);
    }
    /**
     * @param mixed $extension
     * @return Media
     */
    public function setExtension($extension)
    {
        $this->extension = $extension;
        return $this;
    }
    /**
     * @return mixed
     */
    public function getExtension()
    {
        return $this->extension;
    }
    /**
     * @param mixed $name
     * @return Filename
     */
    public function setName($name)
    {
        $this->name = $name;
    }
    /**
     * @return mixed
     */
    public function getName()
    {
        return $this->name;
    }
    /**
     * @return string filename
     */
    public function __toString()
    {
        return join(".", array($this->name, $this->extension));
    }
}

自定义文件名类型的用法

/**
 * @var string|null
 *
 * @ORM'Column(name="background_filename", type="string", length=255, nullable=true)
 *
 * @Serializer'Expose
 * @Serializer'Type("Filename")
 * @Serializer'SerializedName("background_uri")
 */
private $backgroundFilename;

从现在开始,您将获得预览图像的绝对URL background_uri

一种可能的解决方案是定义处理程序。

处理程序允许您更改序列化或反序列化 单一类型/格式组合的过程。

类似的东西

class ImageHandler
{
    public function serialize(VisitorInterface $visitor, 'FQCN'Image $image, array $type, Context $context)
    {
        // do some stuff
        return ...;
    }
}

并在services.yml中注册

serializer.handler.image_handler:
    class: FQCN'Handler'ImageHandler
    arguments: []
    tags:
        - { name: "jms_serializer.handler", type: FQCN'AdvertImage, format: json, method: serialize }
如果我

很好地理解您的问题,您需要在序列化之前更改正确的值,我认为手动可以帮助@Accessor

class User
{
    private $id;
    /** @Accessor(getter="getTrimmedName",setter="setName") */
    private $name;
    // ...
    public function getTrimmedName()
    {
        return trim($this->name);
    }
    public function setName($name)
    {
        $this->name = $name;
    }
}