1*04fd306cSNickeau<?php 2*04fd306cSNickeau 3*04fd306cSNickeaunamespace Facebook\WebDriver; 4*04fd306cSNickeau 5*04fd306cSNickeauuse InvalidArgumentException; 6*04fd306cSNickeau 7*04fd306cSNickeau/** 8*04fd306cSNickeau * Set values of an cookie. 9*04fd306cSNickeau * 10*04fd306cSNickeau * Implements ArrayAccess for backwards compatibility. 11*04fd306cSNickeau * 12*04fd306cSNickeau * @see https://w3c.github.io/webdriver/webdriver-spec.html#cookies 13*04fd306cSNickeau */ 14*04fd306cSNickeauclass Cookie implements \ArrayAccess 15*04fd306cSNickeau{ 16*04fd306cSNickeau /** @var array */ 17*04fd306cSNickeau protected $cookie = []; 18*04fd306cSNickeau 19*04fd306cSNickeau /** 20*04fd306cSNickeau * @param string $name The name of the cookie; may not be null or an empty string. 21*04fd306cSNickeau * @param string $value The cookie value; may not be null. 22*04fd306cSNickeau */ 23*04fd306cSNickeau public function __construct($name, $value) 24*04fd306cSNickeau { 25*04fd306cSNickeau $this->validateCookieName($name); 26*04fd306cSNickeau $this->validateCookieValue($value); 27*04fd306cSNickeau 28*04fd306cSNickeau $this->cookie['name'] = $name; 29*04fd306cSNickeau $this->cookie['value'] = $value; 30*04fd306cSNickeau } 31*04fd306cSNickeau 32*04fd306cSNickeau /** 33*04fd306cSNickeau * @param array $cookieArray The cookie fields; must contain name and value. 34*04fd306cSNickeau * @return Cookie 35*04fd306cSNickeau */ 36*04fd306cSNickeau public static function createFromArray(array $cookieArray) 37*04fd306cSNickeau { 38*04fd306cSNickeau if (!isset($cookieArray['name'])) { 39*04fd306cSNickeau throw new InvalidArgumentException('Cookie name should be set'); 40*04fd306cSNickeau } 41*04fd306cSNickeau if (!isset($cookieArray['value'])) { 42*04fd306cSNickeau throw new InvalidArgumentException('Cookie value should be set'); 43*04fd306cSNickeau } 44*04fd306cSNickeau $cookie = new self($cookieArray['name'], $cookieArray['value']); 45*04fd306cSNickeau 46*04fd306cSNickeau if (isset($cookieArray['path'])) { 47*04fd306cSNickeau $cookie->setPath($cookieArray['path']); 48*04fd306cSNickeau } 49*04fd306cSNickeau if (isset($cookieArray['domain'])) { 50*04fd306cSNickeau $cookie->setDomain($cookieArray['domain']); 51*04fd306cSNickeau } 52*04fd306cSNickeau if (isset($cookieArray['expiry'])) { 53*04fd306cSNickeau $cookie->setExpiry($cookieArray['expiry']); 54*04fd306cSNickeau } 55*04fd306cSNickeau if (isset($cookieArray['secure'])) { 56*04fd306cSNickeau $cookie->setSecure($cookieArray['secure']); 57*04fd306cSNickeau } 58*04fd306cSNickeau if (isset($cookieArray['httpOnly'])) { 59*04fd306cSNickeau $cookie->setHttpOnly($cookieArray['httpOnly']); 60*04fd306cSNickeau } 61*04fd306cSNickeau if (isset($cookieArray['sameSite'])) { 62*04fd306cSNickeau $cookie->setSameSite($cookieArray['sameSite']); 63*04fd306cSNickeau } 64*04fd306cSNickeau 65*04fd306cSNickeau return $cookie; 66*04fd306cSNickeau } 67*04fd306cSNickeau 68*04fd306cSNickeau /** 69*04fd306cSNickeau * @return string 70*04fd306cSNickeau */ 71*04fd306cSNickeau public function getName() 72*04fd306cSNickeau { 73*04fd306cSNickeau return $this->offsetGet('name'); 74*04fd306cSNickeau } 75*04fd306cSNickeau 76*04fd306cSNickeau /** 77*04fd306cSNickeau * @return string 78*04fd306cSNickeau */ 79*04fd306cSNickeau public function getValue() 80*04fd306cSNickeau { 81*04fd306cSNickeau return $this->offsetGet('value'); 82*04fd306cSNickeau } 83*04fd306cSNickeau 84*04fd306cSNickeau /** 85*04fd306cSNickeau * The path the cookie is visible to. Defaults to "/" if omitted. 86*04fd306cSNickeau * 87*04fd306cSNickeau * @param string $path 88*04fd306cSNickeau */ 89*04fd306cSNickeau public function setPath($path) 90*04fd306cSNickeau { 91*04fd306cSNickeau $this->offsetSet('path', $path); 92*04fd306cSNickeau } 93*04fd306cSNickeau 94*04fd306cSNickeau /** 95*04fd306cSNickeau * @return string|null 96*04fd306cSNickeau */ 97*04fd306cSNickeau public function getPath() 98*04fd306cSNickeau { 99*04fd306cSNickeau return $this->offsetGet('path'); 100*04fd306cSNickeau } 101*04fd306cSNickeau 102*04fd306cSNickeau /** 103*04fd306cSNickeau * The domain the cookie is visible to. Defaults to the current browsing context's document's URL domain if omitted. 104*04fd306cSNickeau * 105*04fd306cSNickeau * @param string $domain 106*04fd306cSNickeau */ 107*04fd306cSNickeau public function setDomain($domain) 108*04fd306cSNickeau { 109*04fd306cSNickeau if (mb_strpos($domain, ':') !== false) { 110*04fd306cSNickeau throw new InvalidArgumentException(sprintf('Cookie domain "%s" should not contain a port', $domain)); 111*04fd306cSNickeau } 112*04fd306cSNickeau 113*04fd306cSNickeau $this->offsetSet('domain', $domain); 114*04fd306cSNickeau } 115*04fd306cSNickeau 116*04fd306cSNickeau /** 117*04fd306cSNickeau * @return string|null 118*04fd306cSNickeau */ 119*04fd306cSNickeau public function getDomain() 120*04fd306cSNickeau { 121*04fd306cSNickeau return $this->offsetGet('domain'); 122*04fd306cSNickeau } 123*04fd306cSNickeau 124*04fd306cSNickeau /** 125*04fd306cSNickeau * The cookie's expiration date, specified in seconds since Unix Epoch. 126*04fd306cSNickeau * 127*04fd306cSNickeau * @param int $expiry 128*04fd306cSNickeau */ 129*04fd306cSNickeau public function setExpiry($expiry) 130*04fd306cSNickeau { 131*04fd306cSNickeau $this->offsetSet('expiry', (int) $expiry); 132*04fd306cSNickeau } 133*04fd306cSNickeau 134*04fd306cSNickeau /** 135*04fd306cSNickeau * @return int|null 136*04fd306cSNickeau */ 137*04fd306cSNickeau public function getExpiry() 138*04fd306cSNickeau { 139*04fd306cSNickeau return $this->offsetGet('expiry'); 140*04fd306cSNickeau } 141*04fd306cSNickeau 142*04fd306cSNickeau /** 143*04fd306cSNickeau * Whether this cookie requires a secure connection (https). Defaults to false if omitted. 144*04fd306cSNickeau * 145*04fd306cSNickeau * @param bool $secure 146*04fd306cSNickeau */ 147*04fd306cSNickeau public function setSecure($secure) 148*04fd306cSNickeau { 149*04fd306cSNickeau $this->offsetSet('secure', $secure); 150*04fd306cSNickeau } 151*04fd306cSNickeau 152*04fd306cSNickeau /** 153*04fd306cSNickeau * @return bool|null 154*04fd306cSNickeau */ 155*04fd306cSNickeau public function isSecure() 156*04fd306cSNickeau { 157*04fd306cSNickeau return $this->offsetGet('secure'); 158*04fd306cSNickeau } 159*04fd306cSNickeau 160*04fd306cSNickeau /** 161*04fd306cSNickeau * Whether the cookie is an HTTP only cookie. Defaults to false if omitted. 162*04fd306cSNickeau * 163*04fd306cSNickeau * @param bool $httpOnly 164*04fd306cSNickeau */ 165*04fd306cSNickeau public function setHttpOnly($httpOnly) 166*04fd306cSNickeau { 167*04fd306cSNickeau $this->offsetSet('httpOnly', $httpOnly); 168*04fd306cSNickeau } 169*04fd306cSNickeau 170*04fd306cSNickeau /** 171*04fd306cSNickeau * @return bool|null 172*04fd306cSNickeau */ 173*04fd306cSNickeau public function isHttpOnly() 174*04fd306cSNickeau { 175*04fd306cSNickeau return $this->offsetGet('httpOnly'); 176*04fd306cSNickeau } 177*04fd306cSNickeau 178*04fd306cSNickeau /** 179*04fd306cSNickeau * The cookie's same-site value. 180*04fd306cSNickeau * 181*04fd306cSNickeau * @param string $sameSite 182*04fd306cSNickeau */ 183*04fd306cSNickeau public function setSameSite($sameSite) 184*04fd306cSNickeau { 185*04fd306cSNickeau $this->offsetSet('sameSite', $sameSite); 186*04fd306cSNickeau } 187*04fd306cSNickeau 188*04fd306cSNickeau /** 189*04fd306cSNickeau * @return string|null 190*04fd306cSNickeau */ 191*04fd306cSNickeau public function getSameSite() 192*04fd306cSNickeau { 193*04fd306cSNickeau return $this->offsetGet('sameSite'); 194*04fd306cSNickeau } 195*04fd306cSNickeau 196*04fd306cSNickeau /** 197*04fd306cSNickeau * @return array 198*04fd306cSNickeau */ 199*04fd306cSNickeau public function toArray() 200*04fd306cSNickeau { 201*04fd306cSNickeau $cookie = $this->cookie; 202*04fd306cSNickeau if (!isset($cookie['secure'])) { 203*04fd306cSNickeau // Passing a boolean value for the "secure" flag is mandatory when using geckodriver 204*04fd306cSNickeau $cookie['secure'] = false; 205*04fd306cSNickeau } 206*04fd306cSNickeau 207*04fd306cSNickeau return $cookie; 208*04fd306cSNickeau } 209*04fd306cSNickeau 210*04fd306cSNickeau /** 211*04fd306cSNickeau * @param mixed $offset 212*04fd306cSNickeau * @return bool 213*04fd306cSNickeau */ 214*04fd306cSNickeau #[\ReturnTypeWillChange] 215*04fd306cSNickeau public function offsetExists($offset) 216*04fd306cSNickeau { 217*04fd306cSNickeau return isset($this->cookie[$offset]); 218*04fd306cSNickeau } 219*04fd306cSNickeau 220*04fd306cSNickeau /** 221*04fd306cSNickeau * @param mixed $offset 222*04fd306cSNickeau * @return mixed 223*04fd306cSNickeau */ 224*04fd306cSNickeau #[\ReturnTypeWillChange] 225*04fd306cSNickeau public function offsetGet($offset) 226*04fd306cSNickeau { 227*04fd306cSNickeau return $this->offsetExists($offset) ? $this->cookie[$offset] : null; 228*04fd306cSNickeau } 229*04fd306cSNickeau 230*04fd306cSNickeau /** 231*04fd306cSNickeau * @param mixed $offset 232*04fd306cSNickeau * @param mixed $value 233*04fd306cSNickeau * @return void 234*04fd306cSNickeau */ 235*04fd306cSNickeau #[\ReturnTypeWillChange] 236*04fd306cSNickeau public function offsetSet($offset, $value) 237*04fd306cSNickeau { 238*04fd306cSNickeau if ($value === null) { 239*04fd306cSNickeau unset($this->cookie[$offset]); 240*04fd306cSNickeau } else { 241*04fd306cSNickeau $this->cookie[$offset] = $value; 242*04fd306cSNickeau } 243*04fd306cSNickeau } 244*04fd306cSNickeau 245*04fd306cSNickeau /** 246*04fd306cSNickeau * @param mixed $offset 247*04fd306cSNickeau * @return void 248*04fd306cSNickeau */ 249*04fd306cSNickeau #[\ReturnTypeWillChange] 250*04fd306cSNickeau public function offsetUnset($offset) 251*04fd306cSNickeau { 252*04fd306cSNickeau unset($this->cookie[$offset]); 253*04fd306cSNickeau } 254*04fd306cSNickeau 255*04fd306cSNickeau /** 256*04fd306cSNickeau * @param string $name 257*04fd306cSNickeau */ 258*04fd306cSNickeau protected function validateCookieName($name) 259*04fd306cSNickeau { 260*04fd306cSNickeau if ($name === null || $name === '') { 261*04fd306cSNickeau throw new InvalidArgumentException('Cookie name should be non-empty'); 262*04fd306cSNickeau } 263*04fd306cSNickeau 264*04fd306cSNickeau if (mb_strpos($name, ';') !== false) { 265*04fd306cSNickeau throw new InvalidArgumentException('Cookie name should not contain a ";"'); 266*04fd306cSNickeau } 267*04fd306cSNickeau } 268*04fd306cSNickeau 269*04fd306cSNickeau /** 270*04fd306cSNickeau * @param string $value 271*04fd306cSNickeau */ 272*04fd306cSNickeau protected function validateCookieValue($value) 273*04fd306cSNickeau { 274*04fd306cSNickeau if ($value === null) { 275*04fd306cSNickeau throw new InvalidArgumentException('Cookie value is required when setting a cookie'); 276*04fd306cSNickeau } 277*04fd306cSNickeau } 278*04fd306cSNickeau} 279