I have the field "image" in entities. But depends of action I want to show not original image, but image's preview (which I make in LiipImagineBundle). The one solution which I can imagine:
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,
);
}
But I don't like it, because if an entity has deep children's entities the code will be very confusing.
How to do it correctly?
One possible solution is to define Handler.
Handlers allow you to change the serialization, or deserialization process for a single type/format combination.
Something like
class ImageHandler
{
public function serialize(VisitorInterface $visitor, \FQCN\Image $image, array $type, Context $context)
{
// do some stuff
return ...;
}
}
And register it in services.yml
serializer.handler.image_handler:
class: FQCN\Handler\ImageHandler
arguments: []
tags:
- { name: "jms_serializer.handler", type: FQCN\AdvertImage, format: json, method: serialize }
Common problem when you want to return absolute url through API while using LiipImagine and FOSRest
Change EE\TYSBundle to your own, code taken from https://github.com/EE/TellYourStoryBundle/tree/develop
JMSSerializer Handler Service with injected Cache Manager to get correct prefix
ee_tys.serializer.filename_handler:
class: EE\TYSBundle\Handler\FilenameHandler
arguments:
- "@liip_imagine.cache.manager"
tags:
- { name: 'jms_serializer.handler', type: Filename, format: json}
Handler for custom Filename type
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));
}
}
usage of custom Filename type
/**
* @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;
From now on you will get background_uri with absolute url to your preview Image
If i understand your question well, you need change value for correct before serialisation, i think manual can help @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;
}
}