With Drupal 7, Drupal 8, and Drupal 9 you could use user_cookie_save() to store a cookie.
function user_cookie_save(array $values) { foreach ($values as $field => $value) { // Set cookie for 365 days. setrawcookie('Drupal.visitor.' . $field, rawurlencode($value), REQUEST_TIME + 31536000, '/'); } }
The first parameter is an array, whose keys are the names of the cookies to set and its values are the cookie values.
user_cookie_save() doesn't allow to set when a cookie expires; cookies created with this function expires after 365 days.
The only method that in Drupal 8 calls user_cookie_save() is SystemController::compactPage().
public function compactPage($mode) { user_cookie_save(['admin_compact_mode' => $mode == 'on']); return $this->redirect('<front>'); }
Unfortunately, there isn't an equivalent function to read a cookie. In Drupal 8 and Drupal 9, to read the cookie saved from SystemController::compactPage() it's used system_admin_compact_mode().
function system_admin_compact_mode() { // PHP converts dots into underscores in cookie names to avoid problems with // its parser, so we use a converted cookie name. return \Drupal::request()->cookies->get('Drupal_visitor_admin_compact_mode', \Drupal::config('system.site')->get('admin_compact_mode')); }
In alternative, in Drupal 8 and Drupal 9, you could store cookies using code similar to the one used by BigPipeController::setNoJsCookie() (implemented since Drupal 8.1.x).
if ($request->cookies->has(BigPipeStrategy::NOJS_COOKIE) || !$request->hasSession()) { throw new AccessDeniedHttpException(); } if (!$request->query->has('destination')) { throw new HttpException(400, 'The original location is missing.'); } $response = new LocalRedirectResponse($request->query->get('destination')); // Set cookie without httpOnly, so that JavaScript can delete it. $response->headers->setCookie(new Cookie(BigPipeStrategy::NOJS_COOKIE, TRUE, 0, '/', NULL, FALSE, FALSE, FALSE, NULL)); $response->addCacheableDependency((new CacheableMetadata()) ->addCacheContexts([ 'cookies:' . BigPipeStrategy::NOJS_COOKIE, 'session.exists', ])); return $response;
This code used the $response object from Symfony, instead of using a PHP function.
It's also more "symmetric," as the same object allows to read and write cookies.
Using $response->headers->setCookie() gives more control over the cookie parameters (the parameters Cookie::__construct() accepts).