0

I'm in a bit of a pickle and I hope one of the more advanced Symfony / FOSRestBundle users can help me out with this.

FOSRestBundle returns responses as such:

<?xml version="1.0" encoding="UTF-8"?>
 <result>
  <entry>
  </entry>
 </result>

The thing is, I am storing complete XML blobs in my database because some other systems depend on it, which are as follows:

<profile updated="2015-03-04T10:00">
 <first_name>Peter</first_name>
 <last_name>Pan</last_name>
 <age>34</age>
 <department>Marketing</department>
 <job>Lead Marketing</job>
 <town>New York</town>
 <phone type="work">12345678910</phone>
 <email type="work">user@town.org</email>
</profile>

I store these as complete blobs, is there any way I can return these without having FOSRestBundle add the aforementioned stuff around my own XML?

If anything is unclear feel free to ask me for more information. Thanks in advance!

SliceOfLife
  • 89
  • 2
  • 7
  • You could try not using the `View` object and just return a `Response` with the content set to your XML and the content type to `application/xml`. – qooplmao Mar 13 '15 at 09:59
  • That certainly works! Thank you! I'm just curious if this is the best/nicest approach possible though? – SliceOfLife Mar 13 '15 at 10:27
  • Best would be what works and is clean. Possibly the "nicest" approach would be to work your coding completely around the `FOSRestBundle` but then you would be quite dependent on it and seems like it would require a bunch of unnecessary work. You're still working with a simple `Response` object so it's pretty clean as it is, you could always make a service that generated this for you from the given `XML` code but that depends on your preference and how much you would reuse it. – qooplmao Mar 13 '15 at 10:32

1 Answers1

1

As in my comment you could send a response object with the content set to the XML and with the content type set to application/xml like..

/** @var XMLModelInterface $xmlModel */
/* $xmlModel populated from your database */
$xmlModel = new XMLModel();

$response = new Response(
    $xmlModel->getContent(),
    Response::HTTP_OK,
    array(
        'Content-Type' => 'application/xml',
    )
);

But to add to that, what you could do is set an event listener that listened for the kernel.view (Typical Purposes: Transform a non-Response return value from a controller into a Response) and convert your XMLModelInterface to a response. This would mean that you would only need to return an XMLModelInterface from your controller and you would only have one place to update if you wanted to change the way the response was handled.

I haven't tested this so it might not be bang on correct but as far as I know it would work. I've used some info from FOSRestBundle and the SensionFrameworkExtraBundle so it should be alright.

Event Subscriber

class XMLModelResponseSubscriber implements EventSubscriberInterface
{
    /**
     * Converts a returned XMLModelInterface to a Response object
     *
     * @param GetResponseForControllerResultEvent $event
     */
    public function onKernelView(GetResponseForControllerResultEvent $event)
    {
        // If controller result is not a XMLModelInterface ignore
        if (!is_a($event->getControllerResult(), 'Acme/SomeBundle/Model/XMLModelInterface')) {
            return;
        }

        $response = new Response(
            $event->getControllerResult()->getContent(),
            Response::HTTP_OK,
            array(
                'Content-Type' => 'application/xml',
            )
        );

        $event->setControllerResult($response);
    }

    public static function getSubscribedEvents()
    {
        return array(
            KernelEvents::VIEW => 'onKernelView',
        );
    }
}

Services.yml

services:
    acme.subscriber.xml_model_response:
        class: Acme\SomeBundle\EventSubscriber\XMLModelResponseSubscriber
        tags:
            - { name: kernel.event_subscriber }

Then in your controller you would just do..

/** @var XMLModelInterface $xmlModel */
/* $xmlModel populated from your database */
$xmlModel = new XMLModel();

return $xmlModel;
qooplmao
  • 17,622
  • 2
  • 44
  • 69