CookieCollection.php 7.45 KB
Newer Older
Qiang Xue committed
1 2 3
<?php
/**
 * @link http://www.yiiframework.com/
Qiang Xue committed
4
 * @copyright Copyright (c) 2008 Yii Software LLC
Qiang Xue committed
5 6 7 8 9
 * @license http://www.yiiframework.com/license/
 */

namespace yii\web;

Qiang Xue committed
10
use Yii;
11
use ArrayIterator;
Qiang Xue committed
12 13
use yii\base\InvalidCallException;
use yii\base\Object;
Qiang Xue committed
14 15

/**
16
 * CookieCollection maintains the cookies available in the current request.
Qiang Xue committed
17
 *
18 19 20
 * @property integer $count The number of cookies in the collection. This property is read-only.
 * @property ArrayIterator $iterator An iterator for traversing the cookies in the collection. This property
 * is read-only.
Qiang Xue committed
21 22 23 24
 *
 * @author Qiang Xue <qiang.xue@gmail.com>
 * @since 2.0
 */
25
class CookieCollection extends Object implements \IteratorAggregate, \ArrayAccess, \Countable
Qiang Xue committed
26
{
27 28 29 30 31 32 33 34 35 36
    /**
     * @var boolean whether this collection is read only.
     */
    public $readOnly = false;

    /**
     * @var Cookie[] the cookies in this collection (indexed by the cookie names)
     */
    private $_cookies = [];

37

38 39 40
    /**
     * Constructor.
     * @param array $cookies the cookies that this collection initially contains. This should be
Alexander Makarov committed
41
     * an array of name-value pairs.
42
     * @param array $config name-value pairs that will be used to initialize the object properties
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
     */
    public function __construct($cookies = [], $config = [])
    {
        $this->_cookies = $cookies;
        parent::__construct($config);
    }

    /**
     * Returns an iterator for traversing the cookies in the collection.
     * This method is required by the SPL interface `IteratorAggregate`.
     * It will be implicitly called when you use `foreach` to traverse the collection.
     * @return ArrayIterator an iterator for traversing the cookies in the collection.
     */
    public function getIterator()
    {
        return new ArrayIterator($this->_cookies);
    }

    /**
     * Returns the number of cookies in the collection.
     * This method is required by the SPL `Countable` interface.
     * It will be implicitly called when you use `count($collection)`.
     * @return integer the number of cookies in the collection.
     */
    public function count()
    {
        return $this->getCount();
    }

    /**
     * Returns the number of cookies in the collection.
     * @return integer the number of cookies in the collection.
     */
    public function getCount()
    {
        return count($this->_cookies);
    }

    /**
     * Returns the cookie with the specified name.
83
     * @param string $name the cookie name
84 85 86 87 88 89 90 91 92 93
     * @return Cookie the cookie with the specified name. Null if the named cookie does not exist.
     * @see getValue()
     */
    public function get($name)
    {
        return isset($this->_cookies[$name]) ? $this->_cookies[$name] : null;
    }

    /**
     * Returns the value of the named cookie.
94 95 96
     * @param string $name the cookie name
     * @param mixed $defaultValue the value that should be returned when the named cookie does not exist.
     * @return mixed the value of the named cookie.
97 98 99 100 101 102 103 104 105
     * @see get()
     */
    public function getValue($name, $defaultValue = null)
    {
        return isset($this->_cookies[$name]) ? $this->_cookies[$name]->value : $defaultValue;
    }

    /**
     * Returns whether there is a cookie with the specified name.
106
     * Note that if a cookie is marked for deletion from browser, this method will return false.
107
     * @param string $name the cookie name
108
     * @return boolean whether the named cookie exists
109
     * @see remove()
110 111 112
     */
    public function has($name)
    {
113 114
        return isset($this->_cookies[$name]) && $this->_cookies[$name]->value !== ''
            && ($this->_cookies[$name]->expire === null || $this->_cookies[$name]->expire >= time());
115 116 117 118 119
    }

    /**
     * Adds a cookie to the collection.
     * If there is already a cookie with the same name in the collection, it will be removed first.
120
     * @param Cookie $cookie the cookie to be added
121 122 123 124 125 126 127 128 129 130 131 132 133 134
     * @throws InvalidCallException if the cookie collection is read only
     */
    public function add($cookie)
    {
        if ($this->readOnly) {
            throw new InvalidCallException('The cookie collection is read only.');
        }
        $this->_cookies[$cookie->name] = $cookie;
    }

    /**
     * Removes a cookie.
     * If `$removeFromBrowser` is true, the cookie will be removed from the browser.
     * In this case, a cookie with outdated expiry will be added to the collection.
135 136
     * @param Cookie|string $cookie the cookie object or the name of the cookie to be removed.
     * @param boolean $removeFromBrowser whether to remove the cookie from browser
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
     * @throws InvalidCallException if the cookie collection is read only
     */
    public function remove($cookie, $removeFromBrowser = true)
    {
        if ($this->readOnly) {
            throw new InvalidCallException('The cookie collection is read only.');
        }
        if ($cookie instanceof Cookie) {
            $cookie->expire = 1;
            $cookie->value = '';
        } else {
            $cookie = new Cookie([
                'name' => $cookie,
                'expire' => 1,
            ]);
        }
        if ($removeFromBrowser) {
            $this->_cookies[$cookie->name] = $cookie;
        } else {
            unset($this->_cookies[$cookie->name]);
        }
    }

    /**
     * Removes all cookies.
     * @throws InvalidCallException if the cookie collection is read only
     */
    public function removeAll()
    {
        if ($this->readOnly) {
            throw new InvalidCallException('The cookie collection is read only.');
        }
        $this->_cookies = [];
    }

    /**
     * Returns the collection as a PHP array.
     * @return array the array representation of the collection.
175
     * The array keys are cookie names, and the array values are the corresponding cookie objects.
176 177 178 179 180 181 182 183 184 185
     */
    public function toArray()
    {
        return $this->_cookies;
    }

    /**
     * Returns whether there is a cookie with the specified name.
     * This method is required by the SPL interface `ArrayAccess`.
     * It is implicitly called when you use something like `isset($collection[$name])`.
186
     * @param string $name the cookie name
187 188 189 190 191 192 193 194 195 196 197 198
     * @return boolean whether the named cookie exists
     */
    public function offsetExists($name)
    {
        return $this->has($name);
    }

    /**
     * Returns the cookie with the specified name.
     * This method is required by the SPL interface `ArrayAccess`.
     * It is implicitly called when you use something like `$cookie = $collection[$name];`.
     * This is equivalent to [[get()]].
199
     * @param string $name the cookie name
200 201 202 203 204 205 206 207 208 209 210 211
     * @return Cookie the cookie with the specified name, null if the named cookie does not exist.
     */
    public function offsetGet($name)
    {
        return $this->get($name);
    }

    /**
     * Adds the cookie to the collection.
     * This method is required by the SPL interface `ArrayAccess`.
     * It is implicitly called when you use something like `$collection[$name] = $cookie;`.
     * This is equivalent to [[add()]].
212
     * @param string $name the cookie name
213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230
     * @param Cookie $cookie the cookie to be added
     */
    public function offsetSet($name, $cookie)
    {
        $this->add($cookie);
    }

    /**
     * Removes the named cookie.
     * This method is required by the SPL interface `ArrayAccess`.
     * It is implicitly called when you use something like `unset($collection[$name])`.
     * This is equivalent to [[remove()]].
     * @param string $name the cookie name
     */
    public function offsetUnset($name)
    {
        $this->remove($name);
    }
Qiang Xue committed
231
}