3 * Base include file for SimpleTest
5 * @subpackage WebTester
10 * include other SimpleTest class files
12 require_once(dirname(__FILE__
) . '/url.php');
16 * Cookie data holder. Cookie rules are full of pretty
17 * arbitary stuff. I have used...
18 * http://wp.netscape.com/newsref/std/cookie_spec.html
19 * http://www.cookiecentral.com/faq/
21 * @subpackage WebTester
32 * Constructor. Sets the stored values.
33 * @param string $name Cookie key.
34 * @param string $value Value of cookie.
35 * @param string $path Cookie path if not host wide.
36 * @param string $expiry Expiry date as string.
37 * @param boolean $is_secure Currently ignored.
39 function SimpleCookie($name, $value = false, $path = false, $expiry = false, $is_secure = false) {
42 $this->_value
= $value;
43 $this->_path
= ($path ?
$this->_fixPath($path) : "/");
44 $this->_expiry
= false;
45 if (is_string($expiry)) {
46 $this->_expiry
= strtotime($expiry);
47 } elseif (is_integer($expiry)) {
48 $this->_expiry
= $expiry;
50 $this->_is_secure
= $is_secure;
54 * Sets the host. The cookie rules determine
55 * that the first two parts are taken for
56 * certain TLDs and three for others. If the
57 * new host does not match these rules then the
59 * @param string $host New hostname.
60 * @return boolean True if hostname is valid.
63 function setHost($host) {
64 if ($host = $this->_truncateHost($host)) {
72 * Accessor for the truncated host to which this
74 * @return string Truncated hostname.
82 * Test for a cookie being valid for a host name.
83 * @param string $host Host to test against.
84 * @return boolean True if the cookie would be valid
87 function isValidHost($host) {
88 return ($this->_truncateHost($host) === $this->getHost());
92 * Extracts just the domain part that determines a
93 * cookie's host validity.
94 * @param string $host Host name to truncate.
95 * @return string Domain or false on a bad host.
98 function _truncateHost($host) {
99 $tlds = SimpleUrl
::getAllTopLevelDomains();
100 if (preg_match('/[a-z\-]+\.(' . $tlds . ')$/i', $host, $matches)) {
102 } elseif (preg_match('/[a-z\-]+\.[a-z\-]+\.[a-z\-]+$/i', $host, $matches)) {
110 * @return string Cookie key.
118 * Accessor for value. A deleted cookie will
119 * have an empty string for this.
120 * @return string Cookie value.
123 function getValue() {
124 return $this->_value
;
129 * @return string Valid cookie path.
137 * Tests a path to see if the cookie applies
138 * there. The test path must be longer or
139 * equal to the cookie path.
140 * @param string $path Path to test against.
141 * @return boolean True if cookie valid here.
144 function isValidPath($path) {
146 $this->_fixPath($path),
148 strlen($this->getPath())) == 0);
152 * Accessor for expiry.
153 * @return string Expiry string.
156 function getExpiry() {
157 if (! $this->_expiry
) {
160 return gmdate("D, d M Y H:i:s", $this->_expiry
) . " GMT";
164 * Test to see if cookie is expired against
165 * the cookie format time or timestamp.
166 * Will give true for a session cookie.
167 * @param integer/string $now Time to test against. Result
168 * will be false if this time
169 * is later than the cookie expiry.
170 * Can be either a timestamp integer
171 * or a cookie format date.
174 function isExpired($now) {
175 if (! $this->_expiry
) {
178 if (is_string($now)) {
179 $now = strtotime($now);
181 return ($this->_expiry
< $now);
185 * Ages the cookie by the specified number of
187 * @param integer $interval In seconds.
190 function agePrematurely($interval) {
191 if ($this->_expiry
) {
192 $this->_expiry
-= $interval;
197 * Accessor for the secure flag.
198 * @return boolean True if cookie needs SSL.
201 function isSecure() {
202 return $this->_is_secure
;
206 * Adds a trailing and leading slash to the path
208 * @param string $path Path to fix.
211 function _fixPath($path) {
212 if (substr($path, 0, 1) != '/') {
215 if (substr($path, -1, 1) != '/') {
223 * Repository for cookies. This stuff is a
224 * tiny bit browser dependent.
225 * @package SimpleTest
226 * @subpackage WebTester
228 class SimpleCookieJar
{
232 * Constructor. Jar starts empty.
235 function SimpleCookieJar() {
236 $this->_cookies
= array();
240 * Removes expired and temporary cookies as if
241 * the browser was closed and re-opened.
242 * @param string/integer $now Time to test expiry against.
245 function restartSession($date = false) {
246 $surviving_cookies = array();
247 for ($i = 0; $i < count($this->_cookies
); $i++
) {
248 if (! $this->_cookies
[$i]->getValue()) {
251 if (! $this->_cookies
[$i]->getExpiry()) {
254 if ($date && $this->_cookies
[$i]->isExpired($date)) {
257 $surviving_cookies[] = $this->_cookies
[$i];
259 $this->_cookies
= $surviving_cookies;
263 * Ages all cookies in the cookie jar.
264 * @param integer $interval The old session is moved
265 * into the past by this number
266 * of seconds. Cookies now over
267 * age will be removed.
270 function agePrematurely($interval) {
271 for ($i = 0; $i < count($this->_cookies
); $i++
) {
272 $this->_cookies
[$i]->agePrematurely($interval);
277 * Sets an additional cookie. If a cookie has
278 * the same name and path it is replaced.
279 * @param string $name Cookie key.
280 * @param string $value Value of cookie.
281 * @param string $host Host upon which the cookie is valid.
282 * @param string $path Cookie path if not host wide.
283 * @param string $expiry Expiry date.
286 function setCookie($name, $value, $host = false, $path = '/', $expiry = false) {
287 $cookie = new SimpleCookie($name, $value, $path, $expiry);
289 $cookie->setHost($host);
291 $this->_cookies
[$this->_findFirstMatch($cookie)] = $cookie;
295 * Finds a matching cookie to write over or the
296 * first empty slot if none.
297 * @param SimpleCookie $cookie Cookie to write into jar.
298 * @return integer Available slot.
301 function _findFirstMatch($cookie) {
302 for ($i = 0; $i < count($this->_cookies
); $i++
) {
303 $is_match = $this->_isMatch(
305 $this->_cookies
[$i]->getHost(),
306 $this->_cookies
[$i]->getPath(),
307 $this->_cookies
[$i]->getName());
312 return count($this->_cookies
);
316 * Reads the most specific cookie value from the
317 * browser cookies. Looks for the longest path that
319 * @param string $host Host to search.
320 * @param string $path Applicable path.
321 * @param string $name Name of cookie to read.
322 * @return string False if not present, else the
326 function getCookieValue($host, $path, $name) {
328 foreach ($this->_cookies
as $cookie) {
329 if ($this->_isMatch($cookie, $host, $path, $name)) {
330 if (strlen($cookie->getPath()) > strlen($longest_path)) {
331 $value = $cookie->getValue();
332 $longest_path = $cookie->getPath();
336 return (isset($value) ?
$value : false);
340 * Tests cookie for matching against search
342 * @param SimpleTest $cookie Cookie to test.
343 * @param string $host Host must match.
344 * @param string $path Cookie path must be shorter than
346 * @param string $name Name must match.
347 * @return boolean True if matched.
350 function _isMatch($cookie, $host, $path, $name) {
351 if ($cookie->getName() != $name) {
354 if ($host && $cookie->getHost() && ! $cookie->isValidHost($host)) {
357 if (! $cookie->isValidPath($path)) {
364 * Uses a URL to sift relevant cookies by host and
365 * path. Results are list of strings of form "name=value".
366 * @param SimpleUrl $url Url to select by.
367 * @return array Valid name and value pairs.
370 function selectAsPairs($url) {
372 foreach ($this->_cookies
as $cookie) {
373 if ($this->_isMatch($cookie, $url->getHost(), $url->getPath(), $cookie->getName())) {
374 $pairs[] = $cookie->getName() . '=' . $cookie->getValue();