Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
PhpCookieManager.php
Go to the documentation of this file.
1 <?php
8 
13 use Magento\Framework\HTTP\Header as HttpHeader;
14 use Psr\Log\LoggerInterface;
15 
26 {
32  const MAX_NUM_COOKIES = 50;
33  const MAX_COOKIE_SIZE = 4096;
34  const EXPIRE_NOW_TIME = 1;
41  const KEY_EXPIRE_TIME = 'expiry';
45  private $scope;
46 
50  private $reader;
51 
57  private $logger;
58 
64  private $httpHeader;
65 
72  public function __construct(
73  CookieScopeInterface $scope,
74  CookieReaderInterface $reader,
75  LoggerInterface $logger = null,
76  HttpHeader $httpHeader = null
77  ) {
78  $this->scope = $scope;
79  $this->reader = $reader;
80  $this->logger = $logger ?: ObjectManager::getInstance()->get(LoggerInterface::class);
81  $this->httpHeader = $httpHeader ?: ObjectManager::getInstance()->get(HttpHeader::class);
82  }
83 
98  public function setSensitiveCookie($name, $value, SensitiveCookieMetadata $metadata = null)
99  {
100  $metadataArray = $this->scope->getSensitiveCookieMetadata($metadata)->__toArray();
101  $this->setCookie($name, $value, $metadataArray);
102  }
103 
118  public function setPublicCookie($name, $value, PublicCookieMetadata $metadata = null)
119  {
120  $metadataArray = $this->scope->getPublicCookieMetadata($metadata)->__toArray();
121  $this->setCookie($name, $value, $metadataArray);
122  }
123 
135  protected function setCookie($name, $value, array $metadataArray)
136  {
137  $expire = $this->computeExpirationTime($metadataArray);
138 
139  $this->checkAbilityToSendCookie($name, $value);
140 
141  $phpSetcookieSuccess = setcookie(
142  $name,
143  $value,
144  $expire,
145  $this->extractValue(CookieMetadata::KEY_PATH, $metadataArray, ''),
146  $this->extractValue(CookieMetadata::KEY_DOMAIN, $metadataArray, ''),
147  $this->extractValue(CookieMetadata::KEY_SECURE, $metadataArray, false),
148  $this->extractValue(CookieMetadata::KEY_HTTP_ONLY, $metadataArray, false)
149  );
150 
151  if (!$phpSetcookieSuccess) {
152  $params['name'] = $name;
153  if ($value == '') {
154  throw new FailureToSendException(
155  new Phrase('The cookie with "%name" cookieName couldn\'t be deleted.', $params)
156  );
157  } else {
158  throw new FailureToSendException(
159  new Phrase('The cookie with "%name" cookieName couldn\'t be sent. Please try again later.', $params)
160  );
161  }
162  }
163  }
164 
173  private function sizeOfCookie($name, $value)
174  {
175  // The constant '1' is the length of the equal sign in 'name=value'.
176  return strlen($name) + 1 + strlen($value);
177  }
178 
189  private function checkAbilityToSendCookie($name, $value)
190  {
191  if ($name == '' || preg_match("/[=,; \t\r\n\013\014]/", $name)) {
192  throw new InputException(
193  new Phrase(
194  'Cookie name cannot be empty and cannot contain these characters: =,; \\t\\r\\n\\013\\014'
195  )
196  );
197  }
198 
199  $numCookies = count($_COOKIE);
200 
201  if (!isset($_COOKIE[$name])) {
202  $numCookies++;
203  }
204 
205  $sizeOfCookie = $this->sizeOfCookie($name, $value);
206 
207  if ($numCookies > static::MAX_NUM_COOKIES) {
208  $this->logger->warning(
209  new Phrase('Unable to send the cookie. Maximum number of cookies would be exceeded.'),
210  array_merge($_COOKIE, ['user-agent' => $this->httpHeader->getHttpUserAgent()])
211  );
212  }
213 
214  if ($sizeOfCookie > static::MAX_COOKIE_SIZE) {
215  throw new CookieSizeLimitReachedException(
216  new Phrase(
217  'Unable to send the cookie. Size of \'%name\' is %size bytes.',
218  [
219  'name' => $name,
220  'size' => $sizeOfCookie,
221  ]
222  )
223  );
224  }
225  }
226 
233  private function computeExpirationTime(array $metadataArray)
234  {
235  if (isset($metadataArray[PhpCookieManager::KEY_EXPIRE_TIME])
236  && $metadataArray[PhpCookieManager::KEY_EXPIRE_TIME] < time()
237  ) {
238  $expireTime = $metadataArray[PhpCookieManager::KEY_EXPIRE_TIME];
239  } else {
240  if (isset($metadataArray[CookieMetadata::KEY_DURATION])) {
241  $expireTime = $metadataArray[CookieMetadata::KEY_DURATION] + time();
242  } else {
244  }
245  }
246 
247  return $expireTime;
248  }
249 
259  private function extractValue($parameter, array $metadataArray, $defaultValue)
260  {
261  if (array_key_exists($parameter, $metadataArray)) {
262  return $metadataArray[$parameter];
263  } else {
264  return $defaultValue;
265  }
266  }
267 
275  public function getCookie($name, $default = null)
276  {
277  return $this->reader->getCookie($name, $default);
278  }
279 
291  public function deleteCookie($name, CookieMetadata $metadata = null)
292  {
293  $metadataArray = $this->scope->getCookieMetadata($metadata)->__toArray();
294 
295  // explicitly set an expiration time in the metadataArray.
297 
298  $this->checkAbilityToSendCookie($name, '');
299 
300  // cookie value set to empty string to delete from the remote client
301  $this->setCookie($name, '', $metadataArray);
302 
303  // Remove the cookie
304  unset($_COOKIE[$name]);
305  }
306 }
$value
Definition: gender.phtml:16
$params[\Magento\Store\Model\StoreManager::PARAM_RUN_CODE]
Definition: website.php:18
if(!isset($_GET['name'])) $name
Definition: log.php:14