FOSRestbundle, JMS Serializer and SonataMediaBundle return public url for image
Asked Answered
E

1

8

I'm trying to return a JSON object('Module') with a ManyToOne link to an Sonata\MediaBundle\Entity through FOSRestBundle and JMS Serializer. How should I go about doing that?

Here's a hack that I did, but dont think it's the best practise.

class Module
{
    ...
    /**
     * @var Application\Sonata\MediaBundle\Entity\Media
     *
     * @ORM\ManyToOne(targetEntity="Application\Sonata\MediaBundle\Entity\Media",  inversedBy="module")
     * @ORM\JoinColumn(name="hero_image_id", referencedColumnName="id")
     * @JMS\Expose()
     */
    private $heroImage;
    ...
}

class Media extends BaseMedia
{
   ...
   /**
     * A Quick hack not the best method.
     *
     * @JMS\VirtualProperty
     * @JMS\SerializedName("url")
     *
     * @return string
     */
    public function getUrlMethod()
    {
        global $kernel;

        $imageProvider = $kernel->getContainer()->get('sonata.media.provider.image');

        return $imageProvider->generatePublicUrl($this, 'reference');
    }
    ...
}

thank you!

EDIT Thanks to Tautrimas Pajarskas and the post he mention. Here's the class.

<?php
namespace AXO\APIBundle\Listener\Serialization;

use JMS\DiExtraBundle\Annotation\Service;
use JMS\DiExtraBundle\Annotation\Tag;
use JMS\DiExtraBundle\Annotation\Inject;
use JMS\DiExtraBundle\Annotation\InjectParams;
use JMS\Serializer\EventDispatcher\EventSubscriberInterface;
use JMS\Serializer\EventDispatcher\ObjectEvent;
use JMS\Serializer\GraphNavigator;

/**
 * Add data after serialization
 *
 * @Service("axo.listener.serializationlistener")
 * @Tag("jms_serializer.event_subscriber")
 */
class SerializationListener implements EventSubscriberInterface
{

    /**
     * @inheritdoc
     */
    static public function getSubscribedEvents()
    {
        return array(
            array('event' => 'serializer.post_serialize', 'class' => 'Application\Sonata\MediaBundle\Entity\Media', 'method' => 'onPostSerialize'),
        );
    }

    public function onPostSerialize(ObjectEvent $event)
    {
        global $kernel;
        $imageProvider = $kernel->getContainer()->get('sonata.media.provider.image');

        $event->getVisitor()->addData('url',$imageProvider->generatePublicUrl($event->getObject(), 'reference'));
    }
}
Elaboration answered 23/9, 2013 at 10:28 Comment(2)
And in services.yml you would register the service that way: services: AXO.listener.serializationlistener: class: AXO\APIBundle\Listener\Serialization\SerializationListener tags: - { name: jms_serializer.event_subscriber, event: serializer.post_serialize, method: onPostSerialize }Prague
why not get the provider for $event->getObject()->getProviderName() rather than hardcoded for the image provider?Isauraisbel
F
2

You might want to see Add extra fields using JMS Serializer bundle as it has an example, on how to add additional fields to serialized data that depend on external classes.

Forecastle answered 23/9, 2013 at 11:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.