Skip to content

Commit

Permalink
[Cookie] Refactor cookie and jar
Browse files Browse the repository at this point in the history
  • Loading branch information
GeLoLabs committed Aug 29, 2014
1 parent c967598 commit 1040220
Show file tree
Hide file tree
Showing 15 changed files with 652 additions and 244 deletions.
47 changes: 31 additions & 16 deletions doc/events.md
Original file line number Diff line number Diff line change
Expand Up @@ -432,11 +432,11 @@ $hasCookie = $cookieJar->hasCookie($cookie);
$cookieJar->addCookie($cookie);
$cookieJar->removeCookie($cookie);

// Clear all cookies
$cookieJar->clear();
// Clean expired cookies
$cookieJar->clean();

// Clear expired cookies
$cookieJar->clear(true);
// Clear cookies
$cookieJar->clear($domain, $path, $name);
```

Second, the cookie jar creates the cookies through the `Ivory\HttpAdapter\Event\Cookie\CookieFactoryInterface`
Expand Down Expand Up @@ -481,8 +481,6 @@ foreach ($cookieJar as $cookie) {
$cookies = iterator_to_array($cookieJar);
```

Be aware that when you access cookies, the cookie jar clears expired cookies before serving them.

#### Persistent cookie jar

The persistent cookie jar is described by the `Ivory\HttpAdapter\Event\Cookie\Jar\PersistentCookieJarInterface` and its
Expand Down Expand Up @@ -544,9 +542,11 @@ use Ivory\HttpAdapter\Event\Cookie\Cookie;

$cookie = new Cookie($name, $value, $attributes, $createdAt);

$hasName = $cookie->hasName();
$name = $cookie->getName();
$cookie->setName($name);

$hasValue = $cookie->hasValue();
$value = $cookie->getValue();
$cookie->setValue($value);

Expand All @@ -562,24 +562,39 @@ $value = $cookie->getAttribute($name);
$cookie->setAttribute($name, $value);
$cookie->removeAttribute($name);

$age = $cookie->getAge();
$expired = $cookie->isExpired();

$createdAt = $cookie->getCreatedAt();
$cookie->setCreatedAt($createdAt);
```

$array = $cookie->toArray();
$string = (string) $cookie;
All attribute names are described by the `Ivory\HttpAdapter\Event\Cookie\Cookie::ATTR_*` constants.

To check/get the expiration date according to the `Expires` pr `Max-Age` attribute, you can use the following method:

``` php
$expired = $cookie->isExpired();
$expires = $cookie->getExpires();
```

All attribute names are described by the `Ivory\HttpAdapter\Event\Cookie\Cookie::ATTR_*` constants. Additionally, you
can check if the request matches a request or just matches a part of the request:
Additionally, you can check if the request matches a request or just matches a part of the request:

``` php
$match = $cookie->match($request);
$match = $cookie->matchDomain($request);
$match = $cookie->matchPath($request);
$match = $cookie->matchSecure($request);
$match = $cookie->matchDomain($domain);
$match = $cookie->matchPath($path);
$match = $cookie->matchScheme($scheme);
```

Furthermore, you can compare two cookies:

``` php
$compare = $cookie->compare($otherCookie);
```

You can also convert the cookie into an array or a string:

``` php
$array = $cookie->toArray();
$string = (string) $cookie;
```

### Basic authentication
Expand Down
78 changes: 51 additions & 27 deletions src/Ivory/HttpAdapter/Event/Cookie/Cookie.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@
*/
class Cookie implements CookieInterface
{
/** @var string */
/** @var string|null */
protected $name;

/** @var string */
/** @var string|null */
protected $value;

/** @var array */
Expand All @@ -35,21 +35,25 @@ class Cookie implements CookieInterface
/**
* Creates a cookie.
*
* @param string $name The name.
* @param string $value The value.
* @param array $attributes The attributes.
* @param integer $createdAt The creation date (unix timestamp).
* @param string|null $name The name.
* @param string|null $value The value.
* @param array $attributes The attributes.
* @param integer $createdAt The creation date (unix timestamp).
*/
public function __construct($name, $value, array $attributes, $createdAt)
{
$this->setName($name);
$this->setValue($value);
$this->setAttributes($attributes);
$this->setCreatedAt($createdAt);
}

if (!$this->hasAttribute(self::ATTR_SECURE)) {
$this->setAttribute(self::ATTR_SECURE, false);
}
/**
* {@inheritdoc}
*/
public function hasName()
{
return $this->name !== null;
}

/**
Expand All @@ -68,6 +72,14 @@ public function setName($name)
$this->name = $name;
}

/**
* {@inheritdoc}
*/
public function hasValue()
{
return $this->value !== null;
}

/**
* {@inheritdoc}
*/
Expand Down Expand Up @@ -188,46 +200,59 @@ public function setCreatedAt($createdAt)
/**
* {@inheritdoc}
*/
public function getAge()
public function getExpires()
{
return time() - $this->createdAt;
if ($this->hasAttribute(self::ATTR_EXPIRES)) {
return strtotime($this->getAttribute(self::ATTR_EXPIRES));
}

if ($this->hasAttribute(self::ATTR_MAX_AGE)) {
return $this->createdAt + $this->getAttribute(self::ATTR_MAX_AGE);
}

return false;
}

/**
* {@inheritdoc}
*/
public function isExpired()
{
if ($this->hasAttribute(self::ATTR_MAX_AGE) && ($this->getAge() > $this->getAttribute(self::ATTR_MAX_AGE))) {
return true;
}

if ($this->hasAttribute(self::ATTR_EXPIRES) && (strtotime($this->getAttribute(self::ATTR_EXPIRES)) < time())) {
return true;
}
return ($expires = $this->getExpires()) !== false ? $expires < time() : false;
}

return false;
/**
* {@inheritdoc}
*/
public function compare(CookieInterface $cookie)
{
return $this->name === $cookie->getName()
&& $this->getAttribute(self::ATTR_DOMAIN) === $cookie->getAttribute(self::ATTR_DOMAIN)
&& $this->getAttribute(self::ATTR_PATH) === $cookie->getAttribute(self::ATTR_PATH);
}

/**
* {@inheritdoc}
*/
public function match(InternalRequestInterface $request)
{
return $this->matchDomain($request) && $this->matchPath($request) && $this->matchSecure($request);
$parts = parse_url((string) $request->getUrl());

return $this->matchDomain(isset($parts['host']) ? $parts['host'] : null)
&& $this->matchPath(isset($parts['path']) ? $parts['path'] : null)
&& $this->matchScheme(isset($parts['scheme']) ? $parts['scheme'] : null);
}

/**
* {@inheritdoc}
*/
public function matchDomain(InternalRequestInterface $request)
public function matchDomain($domain)
{
if (!$this->hasAttribute(self::ATTR_DOMAIN)) {
return true;
}

$cookieDomain = $this->getAttribute(self::ATTR_DOMAIN);
$domain = parse_url((string) $request->getUrl(), PHP_URL_HOST);

if (strpos($cookieDomain, '.') === 0) {
return (bool) preg_match('/\b'.preg_quote(substr($cookieDomain, 1), '/').'$/i', $domain);
Expand All @@ -239,28 +264,27 @@ public function matchDomain(InternalRequestInterface $request)
/**
* {@inheritdoc}
*/
public function matchPath(InternalRequestInterface $request)
public function matchPath($path)
{
if (!$this->hasAttribute(self::ATTR_PATH)) {
return true;
}

return strpos(parse_url((string) $request->getUrl(), PHP_URL_PATH), $this->getAttribute(self::ATTR_PATH)) === 0;
return strpos($path, $this->getAttribute(self::ATTR_PATH)) === 0;
}

/**
* {@inheritdoc}
*/
public function matchSecure(InternalRequestInterface $request)
public function matchScheme($scheme)
{
if (!$this->hasAttribute(self::ATTR_SECURE)) {
return true;
}

$secure = $this->getAttribute(self::ATTR_SECURE);
$scheme = parse_url((string) $request->getUrl(), PHP_URL_SCHEME);

return ($secure && $scheme === 'https') || (!$secure && (($scheme === 'http') || empty($scheme)));
return ($secure && $scheme === 'https') || (!$secure && ($scheme === 'http' || $scheme === null));
}

/**
Expand Down
53 changes: 38 additions & 15 deletions src/Ivory/HttpAdapter/Event/Cookie/CookieInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,33 +35,47 @@ interface CookieInterface
/** @const string The expires attribute. */
const ATTR_EXPIRES = 'expires';

/**
* Check if there is a name.
*
* @return boolean TRUE if there is a name else FALSE.
*/
public function hasName();

/**
* Gets the name.
*
* @return string The name.
* @return string|null The name.
*/
public function getName();

/**
* Sets the name.
*
* @param string $name The name.
* @param string|null $name The name.
*
* @return void No return value.
*/
public function setName($name);

/**
* Checks if there is a value.
*
* @return boolean TRUE if there is a value else FALSE.
*/
public function hasValue();

/**
* Gets the value.
*
* @return string The value.
* @return string|null The value.
*/
public function getValue();

/**
* Sets the value.
*
* @param string $value The value.
* @param string|null $value The value.
*
* @return void No return value.
*/
Expand Down Expand Up @@ -169,11 +183,11 @@ public function getCreatedAt();
public function setCreatedAt($createdAt);

/**
* Gets the age.
* Gets the expiration date (unix timestamp).
*
* @return integer The age.
* @return integer|boolean The expiration date (unix timestamp) or FALSE if it never expires.
*/
public function getAge();
public function getExpires();

/**
* Checks if it is expired.
Expand All @@ -182,6 +196,15 @@ public function getAge();
*/
public function isExpired();

/**
* Compares to an other cookie.
*
* @param \Ivory\HttpAdapter\Event\Cookie\CookieInterface $cookie The cookie.
*
* @return boolean TRUE if the cookie is comparable else FALSE.
*/
public function compare(CookieInterface $cookie);

/**
* Checks if it matches the request.
*
Expand All @@ -194,29 +217,29 @@ public function match(InternalRequestInterface $request);
/**
* Checks if it matches the domain.
*
* @param \Ivory\HttpAdapter\Message\InternalRequestInterface $request The request.
* @param string|null $domain The domain.
*
* @return boolean TRUE if it matches the domain else FALSE.
*/
public function matchDomain(InternalRequestInterface $request);
public function matchDomain($domain);

/**
* Checks if it matches the path.
*
* @param \Ivory\HttpAdapter\Message\InternalRequestInterface $request The request.
* @param string|null $path The path.
*
* @return boolean TRUE if it matches the path else FALSE.
*/
public function matchPath(InternalRequestInterface $request);
public function matchPath($path);

/**
* Checks if it matches the secure.
* Checks if it matches the scheme.
*
* @param \Ivory\HttpAdapter\Message\InternalRequestInterface $request The request.
* @param string|null $scheme The scheme.
*
* @return boolean TRUE if it matches the secure else FALSE.
* @return boolean TRUE if it matches the scheme else FALSE.
*/
public function matchSecure(InternalRequestInterface $request);
public function matchScheme($scheme);

/**
* Converts the cookie to array.
Expand Down

0 comments on commit 1040220

Please sign in to comment.