1: <?php
2:
3: namespace Guzzle\Plugin\Cookie\CookieJar;
4:
5: use Guzzle\Plugin\Cookie\Cookie;
6: use Guzzle\Http\Message\RequestInterface;
7: use Guzzle\Http\Message\Response;
8: use Guzzle\Parser\ParserRegistry;
9: use Guzzle\Plugin\Cookie\Exception\InvalidCookieException;
10:
11: 12: 13:
14: class ArrayCookieJar implements CookieJarInterface, \Serializable
15: {
16: 17: 18:
19: protected $cookies = array();
20:
21: 22: 23:
24: protected $strictMode;
25:
26: 27: 28:
29: public function __construct($strictMode = false)
30: {
31: $this->strictMode = $strictMode;
32: }
33:
34: 35: 36: 37: 38: 39: 40:
41: public function setStrictMode($strictMode)
42: {
43: $this->strictMode = $strictMode;
44: }
45:
46: 47: 48:
49: public function remove($domain = null, $path = null, $name = null)
50: {
51: $cookies = $this->all($domain, $path, $name, false, false);
52: $this->cookies = array_filter($this->cookies, function (Cookie $cookie) use ($cookies) {
53: return !in_array($cookie, $cookies, true);
54: });
55:
56: return $this;
57: }
58:
59: 60: 61:
62: public function removeTemporary()
63: {
64: $this->cookies = array_filter($this->cookies, function (Cookie $cookie) {
65: return !$cookie->getDiscard() && $cookie->getExpires();
66: });
67:
68: return $this;
69: }
70:
71: 72: 73:
74: public function removeExpired()
75: {
76: $currentTime = time();
77: $this->cookies = array_filter($this->cookies, function (Cookie $cookie) use ($currentTime) {
78: return !$cookie->getExpires() || $currentTime < $cookie->getExpires();
79: });
80:
81: return $this;
82: }
83:
84: 85: 86:
87: public function all($domain = null, $path = null, $name = null, $skipDiscardable = false, $skipExpired = true)
88: {
89: return array_values(array_filter($this->cookies, function (Cookie $cookie) use (
90: $domain,
91: $path,
92: $name,
93: $skipDiscardable,
94: $skipExpired
95: ) {
96: return false === (($name && $cookie->getName() != $name) ||
97: ($skipExpired && $cookie->isExpired()) ||
98: ($skipDiscardable && ($cookie->getDiscard() || !$cookie->getExpires())) ||
99: ($path && !$cookie->matchesPath($path)) ||
100: ($domain && !$cookie->matchesDomain($domain)));
101: }));
102: }
103:
104: 105: 106:
107: public function add(Cookie $cookie)
108: {
109:
110: $result = $cookie->validate();
111: if ($result !== true) {
112: if ($this->strictMode) {
113: throw new InvalidCookieException($result);
114: } else {
115: return false;
116: }
117: }
118:
119:
120: foreach ($this->cookies as $i => $c) {
121:
122:
123: if ($c->getPath() != $cookie->getPath() ||
124: $c->getDomain() != $cookie->getDomain() ||
125: $c->getPorts() != $cookie->getPorts() ||
126: $c->getName() != $cookie->getName()
127: ) {
128: continue;
129: }
130:
131:
132: if (!$cookie->getDiscard() && $c->getDiscard()) {
133: unset($this->cookies[$i]);
134: continue;
135: }
136:
137:
138: if ($cookie->getExpires() > $c->getExpires()) {
139: unset($this->cookies[$i]);
140: continue;
141: }
142:
143:
144: if ($cookie->getValue() !== $c->getValue()) {
145: unset($this->cookies[$i]);
146: continue;
147: }
148:
149:
150: return false;
151: }
152:
153: $this->cookies[] = $cookie;
154:
155: return true;
156: }
157:
158: 159: 160: 161: 162:
163: public function serialize()
164: {
165:
166: return json_encode(array_map(function (Cookie $cookie) {
167: return $cookie->toArray();
168: }, $this->all(null, null, null, true, true)));
169: }
170:
171: 172: 173:
174: public function unserialize($data)
175: {
176: $data = json_decode($data, true);
177: if (empty($data)) {
178: $this->cookies = array();
179: } else {
180: $this->cookies = array_map(function (array $cookie) {
181: return new Cookie($cookie);
182: }, $data);
183: }
184: }
185:
186: 187: 188: 189: 190:
191: public function count()
192: {
193: return count($this->cookies);
194: }
195:
196: 197: 198: 199: 200:
201: public function getIterator()
202: {
203: return new \ArrayIterator($this->cookies);
204: }
205:
206: 207: 208:
209: public function addCookiesFromResponse(Response $response)
210: {
211: if ($cookieHeader = $response->getSetCookie()) {
212: $request = $response->getRequest();
213: $parser = ParserRegistry::getInstance()->getParser('cookie');
214: foreach ($cookieHeader as $cookie) {
215: if ($parsed = $request
216: ? $parser->parseCookie($cookie, $request->getHost(), $request->getPath())
217: : $parser->parseCookie($cookie)
218: ) {
219:
220: foreach ($parsed['cookies'] as $key => $value) {
221: $row = $parsed;
222: $row['name'] = $key;
223: $row['value'] = $value;
224: unset($row['cookies']);
225: $this->add(new Cookie($row));
226: }
227: }
228: }
229: }
230: }
231:
232: 233: 234:
235: public function getMatchingCookies(RequestInterface $request)
236: {
237:
238: $cookies = $this->all($request->getHost(), $request->getPath());
239:
240: foreach ($cookies as $index => $cookie) {
241: if (!$cookie->matchesPort($request->getPort()) || ($cookie->getSecure() && $request->getScheme() != 'https')) {
242: unset($cookies[$index]);
243: }
244: };
245:
246: return $cookies;
247: }
248: }
249: