1

I read on Deprecate user_cookie_save() and user_cookie_delete(). that user_cookie_save() will be deprecated in Drupal 9 and that we should now use the Symfony's method, as in the following code.

$response = new Response();
$response->headers->setCookie(new Cookie('foo', 'bar'));
return $response->send();

If I use that code in a submission handler of a custom form, $response-send() just returns an empty page, rather than my site. What am I missing here?

EDIT:

OK, so I moved my cookie setting code to a controller method:

public function setusercookies($zip, $license){
    $destination = urldecode(\Drupal::request()->query->get('destination'));
    $response = new RedirectResponse(!empty($destination) ? $destination : '/');
    $response->headers->setCookie(new Cookie('zip', $zip, strtotime( '+1 year' ), '/'));
    $response->headers->setCookie(new Cookie('license', $license, strtotime( '+1 year' ), '/'));
    $response->send();
    return $response;
}

And in my form's submitForm function:

$form_state->setRedirect('mycontroller.setusercookies', [
      'zip' => $zip,
      'license' => $license
    ], [
      'destination' => $destination
    ]);

In both Chrome and Firefox inspectors, I can see that the cookies are set, but now I can't get them back out. I've tried both:

$zip = \Drupal::request()->cookies->get('zip', 'oops');
/* and */
$zip = $_COOKIE['zip'];

UPDATE 2: Starting to think it's an environment issue ... lando with pantheon recipe.

SOLVED: The entire time it seems it was a platform issue:

https://pantheon.io/docs/caching-advanced-topics/#using-your-own-session-style-cookies

2

You can't send a response from custom code in Drupal. You have to return it from a controller.

You can also set a response or add the cookie to an existing response in an event subscriber. In your case set the response in form submit, then Drupal does this for you in a core event subscriber:

$form_state->setResponse($response);

To avoid the empty page you probably want to fill the response with content or add the cookie to a redirect response to display a different page.


Don't $response->send()

To explain why not to send a response. When you find a code example for the Symfony component HttpFoundation sending a response, it isn't valid for custom code in Drupal. See the warning in this doc:

This article explains how to use the HttpFoundation features as an independent component in any PHP application. In Symfony applications everything is already configured and ready to use. Read the Controller article to learn about how to use these features when creating controllers.

In addition the Drupal kernel is wrapped in stack middlewares using Stack/Builder. So sending a response can even be a security risk if you have for example installed a middleware providing security checks.

  • I moved my cookie setting to a controller method and edited the original question. – Delford Chaffin Mar 26 at 19:05
  • In the controller return $response; is all you need to do, don't $response->send();. I tried to make it more clear in the answer. About the Pantheon/Lando environment, there might be a naming issue for the cookie, see drupal.stackexchange.com/questions/274485/… – 4k4 Mar 26 at 20:35
  • Thanks so much for your help! I had been on a page in the Pantheon docs about cookies, but it didn't mention the SESS prefix was needed. What a nightmare that was. – Delford Chaffin Mar 27 at 4:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.