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'));
    }
}
hongpang
  • 93
  • 1
  • 6
  • 1
    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 }` – Vaseltior May 08 '15 at 22:04
  • why not get the provider for $event->getObject()->getProviderName() rather than hardcoded for the image provider? – ppetermann Jun 05 '15 at 12:07

1 Answers1

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.

Community
  • 1
  • 1
TautrimasPajarskas
  • 2,686
  • 1
  • 32
  • 40