Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I give a Symfony 2 service the ability to read and write cookies?

I have a service that should be able to read and write cookies. To do that in a Symfony-like manner, the service must have access to the request and the response. I can imagine that it's possible to pass the request to the service through the service configuration, but I don't know how. I'm not sure how I'm going to give the service the ability to write cookies though. Any suggestions on how to do this would be appreciated.

Note: I really don't want to have to manually pass variables to the service every time I use it.

like image 729
Hubro Avatar asked May 14 '13 06:05

Hubro


2 Answers

I think you really have a couple of options - it really depends on what you are trying to store in a cookie and at what point in the process you need to read do the work.

I suggest your first option is to create a service, that has access the the request and creates a response, which it returns ...

Define your service in services.yml :

services:
    a_service:
        class:     Acme\DemoBundle\RequestServiceClass
        arguments: [@request]
        scope: request

Your class :

//Acme\DemoBundle\RequestServiceClass.php
class RequestServiceClass
{
    private $request;
    public function __construct(Request $request){
         $this->request= $request;
   }

    public function doSomething(){
        // get cookie
        $value = $this->request->cookies->get('cookie');

        // create cookie
        $cookie = new Cookie('cookie', 'value', time() + 3600 * 24 * 7);
        // create response
        $response = new Response();
        // set cookie in response
        $response->headers->setCookie($cookie);
        return $response;
    }
}

Then to use your service you do something like this

public myAction()
{
    $response = $this->get('a_service')->doSomething();
    return $response;
}

The other way of doing it, is to create a kernel.response listener ... its done like this :

Add a service to services.yml :

services:
  a_listener:
    class: Acme\DemoBundle\MyListener
    tags:
      - { name: kernel.event_listener, event: kernel.response, method: onKernelResponse }

Your listener class looks like this :

// Acme\DemoBundle\MyListener.php

class MyListener
{
    public function onKernelResponse(FilterResponseEvent $event)
    {
        $response = $event->getResponse();
        $request  = $event->getRequest();

        // get cookie
        $value = $request->cookies->get('cookie');

        // create cookie
        $cookie = new Cookie('cookie', 'value', time() + 3600 * 24 * 7);
        // set cookie in response
        $response->headers->setCookie($cookie);
    }
}

The difference between the 2 methods is what information is available at the time of process - for example the service has access to everything you pass it ... the response listener has access to everything in the request and the response - you could check if the response is as expected (ie format or content) and then set a cookie according to that.

Some links to some useful documentation to read :

  • kernal.response event
  • HTTPKernal Component
  • Services Scopes
like image 184
Manse Avatar answered Oct 16 '22 16:10

Manse


HTTP stops at the controllers and listeners of HTTP related events. A service (which is not a controller or an HTTP event listener) should not set or get cookies. Instead the controller should handle the cookie. It gets the data from cookie before consuming the service's methods which accept it as argument and return its new value or using a by-reference argument. This way your service is decoupled from HTTP and can be easily re-used ans tested.

like image 1
Pierre Buyle Avatar answered Oct 16 '22 15:10

Pierre Buyle