vendor/symfony/src/Symfony/Component/BrowserKit/Cookie.php
changeset 0 7f95f8617b0b
equal deleted inserted replaced
-1:000000000000 0:7f95f8617b0b
       
     1 <?php
       
     2 
       
     3 /*
       
     4  * This file is part of the Symfony package.
       
     5  *
       
     6  * (c) Fabien Potencier <fabien@symfony.com>
       
     7  *
       
     8  * For the full copyright and license information, please view the LICENSE
       
     9  * file that was distributed with this source code.
       
    10  */
       
    11 
       
    12 namespace Symfony\Component\BrowserKit;
       
    13 
       
    14 /**
       
    15  * Cookie represents an HTTP cookie.
       
    16  *
       
    17  * @author Fabien Potencier <fabien@symfony.com>
       
    18  *
       
    19  * @api
       
    20  */
       
    21 class Cookie
       
    22 {
       
    23     /**
       
    24      * Handles dates as defined by RFC 2616 section 3.3.1, and also some other
       
    25      * non-standard, but common formats.
       
    26      *
       
    27      * @var array
       
    28      */
       
    29     private static $dateFormats = array(
       
    30         'D, d M Y H:i:s T',
       
    31         'D, d-M-y H:i:s T',
       
    32         'D, d-M-Y H:i:s T',
       
    33         'D M j G:i:s Y',
       
    34     );
       
    35 
       
    36     protected $name;
       
    37     protected $value;
       
    38     protected $expires;
       
    39     protected $path;
       
    40     protected $domain;
       
    41     protected $secure;
       
    42     protected $httponly;
       
    43     protected $rawValue;
       
    44 
       
    45     /**
       
    46      * Sets a cookie.
       
    47      *
       
    48      * @param  string  $name         The cookie name
       
    49      * @param  string  $value        The value of the cookie
       
    50      * @param  string  $expires      The time the cookie expires
       
    51      * @param  string  $path         The path on the server in which the cookie will be available on
       
    52      * @param  string  $domain       The domain that the cookie is available
       
    53      * @param  Boolean $secure       Indicates that the cookie should only be transmitted over a secure HTTPS connection from the client
       
    54      * @param  Boolean $httponly     The cookie httponly flag
       
    55      * @param  Boolean $encodedValue Whether the value is encoded or not
       
    56      *
       
    57      * @api
       
    58      */
       
    59     public function __construct($name, $value, $expires = null, $path = null, $domain = '', $secure = false, $httponly = true, $encodedValue = false)
       
    60     {
       
    61         if ($encodedValue) {
       
    62             $this->value    = urldecode($value);
       
    63             $this->rawValue = $value;
       
    64         } else {
       
    65             $this->value    = $value;
       
    66             $this->rawValue = urlencode($value);
       
    67         }
       
    68         $this->name     = $name;
       
    69         $this->expires  = null === $expires ? null : (integer) $expires;
       
    70         $this->path     = empty($path) ? null : $path;
       
    71         $this->domain   = $domain;
       
    72         $this->secure   = (Boolean) $secure;
       
    73         $this->httponly = (Boolean) $httponly;
       
    74     }
       
    75 
       
    76     /**
       
    77      * Returns the HTTP representation of the Cookie.
       
    78      *
       
    79      * @return string The HTTP representation of the Cookie
       
    80      *
       
    81      * @api
       
    82      */
       
    83     public function __toString()
       
    84     {
       
    85         $cookie = sprintf('%s=%s', $this->name, $this->rawValue);
       
    86 
       
    87         if (null !== $this->expires) {
       
    88             $cookie .= '; expires='.substr(\DateTime::createFromFormat('U', $this->expires, new \DateTimeZone('GMT'))->format(self::$dateFormats[0]), 0, -5);
       
    89         }
       
    90 
       
    91         if ('' !== $this->domain) {
       
    92             $cookie .= '; domain='.$this->domain;
       
    93         }
       
    94 
       
    95         if (null !== $this->path) {
       
    96             $cookie .= '; path='.$this->path;
       
    97         }
       
    98 
       
    99         if ($this->secure) {
       
   100             $cookie .= '; secure';
       
   101         }
       
   102 
       
   103         if ($this->httponly) {
       
   104             $cookie .= '; httponly';
       
   105         }
       
   106 
       
   107         return $cookie;
       
   108     }
       
   109 
       
   110     /**
       
   111      * Creates a Cookie instance from a Set-Cookie header value.
       
   112      *
       
   113      * @param string $cookie A Set-Cookie header value
       
   114      * @param string $url    The base URL
       
   115      *
       
   116      * @return Cookie A Cookie instance
       
   117      *
       
   118      * @api
       
   119      */
       
   120     static public function fromString($cookie, $url = null)
       
   121     {
       
   122         $parts = explode(';', $cookie);
       
   123 
       
   124         if (false === strpos($parts[0], '=')) {
       
   125             throw new \InvalidArgumentException('The cookie string "%s" is not valid.');
       
   126         }
       
   127 
       
   128         list($name, $value) = explode('=', array_shift($parts), 2);
       
   129 
       
   130         $values = array(
       
   131             'name'     => trim($name),
       
   132             'value'    => trim($value),
       
   133             'expires'  =>  null,
       
   134             'path'     => null,
       
   135             'domain'   => '',
       
   136             'secure'   => false,
       
   137             'httponly' => false,
       
   138             'passedRawValue' => true,
       
   139         );
       
   140 
       
   141         if (null !== $url) {
       
   142             if ((false === $urlParts = parse_url($url)) || !isset($urlParts['host']) || !isset($urlParts['path'])) {
       
   143                 throw new \InvalidArgumentException(sprintf('The URL "%s" is not valid.', $url));
       
   144             }
       
   145             $parts = array_merge($urlParts, $parts);
       
   146 
       
   147             $values['domain'] = $parts['host'];
       
   148             $values['path'] = substr($parts['path'], 0, strrpos($parts['path'], '/'));
       
   149         }
       
   150 
       
   151         foreach ($parts as $part) {
       
   152             $part = trim($part);
       
   153 
       
   154             if ('secure' === strtolower($part)) {
       
   155                 // Ignore the secure flag if the original URI is not given or is not HTTPS
       
   156                 if (!$url || !isset($urlParts['scheme']) || 'https' != $urlParts['scheme']) {
       
   157                     continue;
       
   158                 }
       
   159 
       
   160                 $values['secure'] = true;
       
   161 
       
   162                 continue;
       
   163             }
       
   164 
       
   165             if ('httponly' === strtolower($part)) {
       
   166                 $values['httponly'] = true;
       
   167 
       
   168                 continue;
       
   169             }
       
   170 
       
   171             if (2 === count($elements = explode('=', $part, 2))) {
       
   172                 if ('expires' === $elements[0]) {
       
   173                     $elements[1] = self::parseDate($elements[1]);
       
   174                 }
       
   175 
       
   176                 $values[strtolower($elements[0])] = $elements[1];
       
   177             }
       
   178         }
       
   179 
       
   180         return new static(
       
   181             $values['name'],
       
   182             $values['value'],
       
   183             $values['expires'],
       
   184             $values['path'],
       
   185             $values['domain'],
       
   186             $values['secure'],
       
   187             $values['httponly'],
       
   188             $values['passedRawValue']
       
   189         );
       
   190     }
       
   191 
       
   192     private static function parseDate($dateValue)
       
   193     {
       
   194         // trim single quotes around date if present
       
   195         if (($length = strlen($dateValue)) > 1 && "'" === $dateValue[0] && "'" === $dateValue[$length-1]) {
       
   196             $dateValue = substr($dateValue, 1, -1);
       
   197         }
       
   198 
       
   199         foreach (self::$dateFormats as $dateFormat) {
       
   200             if (false !== $date = \DateTime::createFromFormat($dateFormat, $dateValue, new \DateTimeZone('GMT'))) {
       
   201                 return $date->getTimestamp();
       
   202             }
       
   203         }
       
   204 
       
   205         throw new \InvalidArgumentException(sprintf('Could not parse date "%s".', $dateValue));
       
   206     }
       
   207 
       
   208     /**
       
   209      * Gets the name of the cookie.
       
   210      *
       
   211      * @return string The cookie name
       
   212      *
       
   213      * @api
       
   214      */
       
   215     public function getName()
       
   216     {
       
   217         return $this->name;
       
   218     }
       
   219 
       
   220     /**
       
   221      * Gets the value of the cookie.
       
   222      *
       
   223      * @return string The cookie value
       
   224      *
       
   225      * @api
       
   226      */
       
   227     public function getValue()
       
   228     {
       
   229         return $this->value;
       
   230     }
       
   231 
       
   232     /**
       
   233      * Gets the raw value of the cookie.
       
   234      *
       
   235      * @return string The cookie value
       
   236      *
       
   237      * @api
       
   238      */
       
   239     public function getRawValue()
       
   240     {
       
   241         return $this->rawValue;
       
   242     }
       
   243 
       
   244     /**
       
   245      * Gets the expires time of the cookie.
       
   246      *
       
   247      * @return string The cookie expires time
       
   248      *
       
   249      * @api
       
   250      */
       
   251     public function getExpiresTime()
       
   252     {
       
   253         return $this->expires;
       
   254     }
       
   255 
       
   256     /**
       
   257      * Gets the path of the cookie.
       
   258      *
       
   259      * @return string The cookie path
       
   260      *
       
   261      * @api
       
   262      */
       
   263     public function getPath()
       
   264     {
       
   265         return null !== $this->path ? $this->path : '/';
       
   266     }
       
   267 
       
   268     /**
       
   269      * Gets the domain of the cookie.
       
   270      *
       
   271      * @return string The cookie domain
       
   272      *
       
   273      * @api
       
   274      */
       
   275     public function getDomain()
       
   276     {
       
   277         return $this->domain;
       
   278     }
       
   279 
       
   280     /**
       
   281      * Returns the secure flag of the cookie.
       
   282      *
       
   283      * @return Boolean The cookie secure flag
       
   284      *
       
   285      * @api
       
   286      */
       
   287     public function isSecure()
       
   288     {
       
   289         return $this->secure;
       
   290     }
       
   291 
       
   292     /**
       
   293      * Returns the httponly flag of the cookie.
       
   294      *
       
   295      * @return Boolean The cookie httponly flag
       
   296      *
       
   297      * @api
       
   298      */
       
   299     public function isHttpOnly()
       
   300     {
       
   301         return $this->httponly;
       
   302     }
       
   303 
       
   304     /**
       
   305      * Returns true if the cookie has expired.
       
   306      *
       
   307      * @return Boolean true if the cookie has expired, false otherwise
       
   308      *
       
   309      * @api
       
   310      */
       
   311     public function isExpired()
       
   312     {
       
   313         return null !== $this->expires && 0 !== $this->expires && $this->expires < time();
       
   314     }
       
   315 }