Source for file cookies.php

Documentation is available at cookies.php

  1. <?php
  2. /**
  3.  *  Base include file for SimpleTest
  4.  *  @package    SimpleTest
  5.  *  @subpackage WebTester
  6.  *  @version    $Id: cookies.php 1723 2008-04-08 00:34:10Z lastcraft $
  7.  */
  8.  
  9. /**#@+
  10.  *  include other SimpleTest class files
  11.  */
  12. require_once(dirname(__FILE__'/url.php');
  13. /**#@-*/
  14.  
  15.  *    Cookie data holder. Cookie rules are full of pretty
  16.  *    arbitary stuff. I have used...
  17.  *    http://wp.netscape.com/newsref/std/cookie_spec.html
  18.  *    http://www.cookiecentral.com/faq/
  19.  *    @package SimpleTest
  20.  *    @subpackage WebTester
  21.  */
  22. class SimpleCookie {
  23.     var $_host;
  24.     var $_name;
  25.     var $_value;
  26.     var $_path;
  27.     var $_expiry;
  28.     var $_is_secure;
  29.     
  30.     /**
  31.      *    Constructor. Sets the stored values.
  32.      *    @param string $name            Cookie key.
  33.      *    @param string $value           Value of cookie.
  34.      *    @param string $path            Cookie path if not host wide.
  35.      *    @param string $expiry          Expiry date as string.
  36.      *    @param boolean $is_secure      Currently ignored.
  37.      */
  38.     function SimpleCookie($name$value false$path false$expiry false$is_secure false{
  39.         $this->_host = false;
  40.         $this->_name = $name;
  41.         $this->_value = $value;
  42.         $this->_path = ($path $this->_fixPath($path"/");
  43.         $this->_expiry = false;
  44.         if (is_string($expiry)) {
  45.             $this->_expiry = strtotime($expiry);
  46.         elseif (is_integer($expiry)) {
  47.             $this->_expiry = $expiry;
  48.         }
  49.         $this->_is_secure = $is_secure;
  50.     }
  51.     
  52.     /**
  53.      *    Sets the host. The cookie rules determine
  54.      *    that the first two parts are taken for
  55.      *    certain TLDs and three for others. If the
  56.      *    new host does not match these rules then the
  57.      *    call will fail.
  58.      *    @param string $host       New hostname.
  59.      *    @return boolean           True if hostname is valid.
  60.      *    @access public
  61.      */
  62.     function setHost($host{
  63.         if ($host $this->_truncateHost($host)) {
  64.             $this->_host = $host;
  65.             return true;
  66.         }
  67.         return false;
  68.     }
  69.     
  70.     /**
  71.      *    Accessor for the truncated host to which this
  72.      *    cookie applies.
  73.      *    @return string       Truncated hostname.
  74.      *    @access public
  75.      */
  76.     function getHost({
  77.         return $this->_host;
  78.     }
  79.     
  80.     /**
  81.      *    Test for a cookie being valid for a host name.
  82.      *    @param string $host    Host to test against.
  83.      *    @return boolean        True if the cookie would be valid
  84.      *                            here.
  85.      */
  86.     function isValidHost($host{
  87.         return ($this->_truncateHost($host=== $this->getHost());
  88.     }
  89.     
  90.     /**
  91.      *    Extracts just the domain part that determines a
  92.      *    cookie's host validity.
  93.      *    @param string $host    Host name to truncate.
  94.      *    @return string        Domain or false on a bad host.
  95.      *    @access private
  96.      */
  97.     function _truncateHost($host{
  98.         $tlds SimpleUrl::getAllTopLevelDomains();
  99.         if (preg_match('/[a-z\-]+\.(' $tlds ')$/i'$host$matches)) {
  100.             return $matches[0];
  101.         elseif (preg_match('/[a-z\-]+\.[a-z\-]+\.[a-z\-]+$/i'$host$matches)) {
  102.             return $matches[0];
  103.         }
  104.         return false;
  105.     }
  106.     
  107.     /**
  108.      *    Accessor for name.
  109.      *    @return string       Cookie key.
  110.      *    @access public
  111.      */
  112.     function getName({
  113.         return $this->_name;
  114.     }
  115.     
  116.     /**
  117.      *    Accessor for value. A deleted cookie will
  118.      *    have an empty string for this.
  119.      *    @return string       Cookie value.
  120.      *    @access public
  121.      */
  122.     function getValue({
  123.         return $this->_value;
  124.     }
  125.     
  126.     /**
  127.      *    Accessor for path.
  128.      *    @return string       Valid cookie path.
  129.      *    @access public
  130.      */
  131.     function getPath({
  132.         return $this->_path;
  133.     }
  134.     
  135.     /**
  136.      *    Tests a path to see if the cookie applies
  137.      *    there. The test path must be longer or
  138.      *    equal to the cookie path.
  139.      *    @param string $path       Path to test against.
  140.      *    @return boolean           True if cookie valid here.
  141.      *    @access public
  142.      */
  143.     function isValidPath($path{
  144.         return (strncmp(
  145.                 $this->_fixPath($path),
  146.                 $this->getPath(),
  147.                 strlen($this->getPath())) == 0);
  148.     }
  149.     
  150.     /**
  151.      *    Accessor for expiry.
  152.      *    @return string       Expiry string.
  153.      *    @access public
  154.      */
  155.     function getExpiry({
  156.         if ($this->_expiry{
  157.             return false;
  158.         }
  159.         return gmdate("D, d M Y H:i:s"$this->_expiry" GMT";
  160.     }
  161.     
  162.     /**
  163.      *    Test to see if cookie is expired against
  164.      *    the cookie format time or timestamp.
  165.      *    Will give true for a session cookie.
  166.      *    @param integer/string $now  Time to test against. Result
  167.      *                                 will be false if this time
  168.      *                                 is later than the cookie expiry.
  169.      *                                 Can be either a timestamp integer
  170.      *                                 or a cookie format date.
  171.      *    @access public
  172.      */
  173.     function isExpired($now{
  174.         if ($this->_expiry{
  175.             return true;
  176.         }
  177.         if (is_string($now)) {
  178.             $now strtotime($now);
  179.         }
  180.         return ($this->_expiry < $now);
  181.     }
  182.     
  183.     /**
  184.      *    Ages the cookie by the specified number of
  185.      *    seconds.
  186.      *    @param integer $interval   In seconds.
  187.      *    @public
  188.      */
  189.     function agePrematurely($interval{
  190.         if ($this->_expiry{
  191.             $this->_expiry -= $interval;
  192.         }
  193.     }
  194.     
  195.     /**
  196.      *    Accessor for the secure flag.
  197.      *    @return boolean       True if cookie needs SSL.
  198.      *    @access public
  199.      */
  200.     function isSecure({
  201.         return $this->_is_secure;
  202.     }
  203.     
  204.     /**
  205.      *    Adds a trailing and leading slash to the path
  206.      *    if missing.
  207.      *    @param string $path            Path to fix.
  208.      *    @access private
  209.      */
  210.     function _fixPath($path{
  211.         if (substr($path01!= '/'{
  212.             $path '/' $path;
  213.         }
  214.         if (substr($path-11!= '/'{
  215.             $path .= '/';
  216.         }
  217.         return $path;
  218.     }
  219. }
  220.  
  221. /**
  222.  *    Repository for cookies. This stuff is a
  223.  *    tiny bit browser dependent.
  224.  *    @package SimpleTest
  225.  *    @subpackage WebTester
  226.  */
  227. class SimpleCookieJar {
  228.     var $_cookies;
  229.     
  230.     /**
  231.      *    Constructor. Jar starts empty.
  232.      *    @access public
  233.      */
  234.     function SimpleCookieJar({
  235.         $this->_cookies = array();
  236.     }
  237.     
  238.     /**
  239.      *    Removes expired and temporary cookies as if
  240.      *    the browser was closed and re-opened.
  241.      *    @param string/integer $now   Time to test expiry against.
  242.      *    @access public
  243.      */
  244.     function restartSession($date false{
  245.         $surviving_cookies array();
  246.         for ($i 0$i count($this->_cookies)$i++{
  247.             if ($this->_cookies[$i]->getValue()) {
  248.                 continue;
  249.             }
  250.             if ($this->_cookies[$i]->getExpiry()) {
  251.                 continue;
  252.             }
  253.             if ($date && $this->_cookies[$i]->isExpired($date)) {
  254.                 continue;
  255.             }
  256.             $surviving_cookies[$this->_cookies[$i];
  257.         }
  258.         $this->_cookies = $surviving_cookies;
  259.     }
  260.     
  261.     /**
  262.      *    Ages all cookies in the cookie jar.
  263.      *    @param integer $interval     The old session is moved
  264.      *                                  into the past by this number
  265.      *                                  of seconds. Cookies now over
  266.      *                                  age will be removed.
  267.      *    @access public
  268.      */
  269.     function agePrematurely($interval{
  270.         for ($i 0$i count($this->_cookies)$i++{
  271.             $this->_cookies[$i]->agePrematurely($interval);
  272.         }
  273.     }
  274.     
  275.     /**
  276.      *    Sets an additional cookie. If a cookie has
  277.      *    the same name and path it is replaced.
  278.      *    @param string $name       Cookie key.
  279.      *    @param string $value      Value of cookie.
  280.      *    @param string $host       Host upon which the cookie is valid.
  281.      *    @param string $path       Cookie path if not host wide.
  282.      *    @param string $expiry     Expiry date.
  283.      *    @access public
  284.      */
  285.     function setCookie($name$value$host false$path '/'$expiry false{
  286.         $cookie new SimpleCookie($name$value$path$expiry);
  287.         if ($host{
  288.             $cookie->setHost($host);
  289.         }
  290.         $this->_cookies[$this->_findFirstMatch($cookie)$cookie;
  291.     }
  292.     
  293.     /**
  294.      *    Finds a matching cookie to write over or the
  295.      *    first empty slot if none.
  296.      *    @param SimpleCookie $cookie    Cookie to write into jar.
  297.      *    @return integer                Available slot.
  298.      *    @access private
  299.      */
  300.     function _findFirstMatch($cookie{
  301.         for ($i 0$i count($this->_cookies)$i++{
  302.             $is_match $this->_isMatch(
  303.                     $cookie,
  304.                     $this->_cookies[$i]->getHost(),
  305.                     $this->_cookies[$i]->getPath(),
  306.                     $this->_cookies[$i]->getName());
  307.             if ($is_match{
  308.                 return $i;
  309.             }
  310.         }
  311.         return count($this->_cookies);
  312.     }
  313.     
  314.     /**
  315.      *    Reads the most specific cookie value from the
  316.      *    browser cookies. Looks for the longest path that
  317.      *    matches.
  318.      *    @param string $host        Host to search.
  319.      *    @param string $path        Applicable path.
  320.      *    @param string $name        Name of cookie to read.
  321.      *    @return string             False if not present, else the
  322.      *                                value as a string.
  323.      *    @access public
  324.      */
  325.     function getCookieValue($host$path$name{
  326.         $longest_path '';
  327.         foreach ($this->_cookies as $cookie{
  328.             if ($this->_isMatch($cookie$host$path$name)) {
  329.                 if (strlen($cookie->getPath()) strlen($longest_path)) {
  330.                     $value $cookie->getValue();
  331.                     $longest_path $cookie->getPath();
  332.                 }
  333.             }
  334.         }
  335.         return (isset($value$value false);
  336.     }
  337.     
  338.     /**
  339.      *    Tests cookie for matching against search
  340.      *    criteria.
  341.      *    @param SimpleTest $cookie    Cookie to test.
  342.      *    @param string $host          Host must match.
  343.      *    @param string $path          Cookie path must be shorter than
  344.      *                                  this path.
  345.      *    @param string $name          Name must match.
  346.      *    @return boolean              True if matched.
  347.      *    @access private
  348.      */
  349.     function _isMatch($cookie$host$path$name{
  350.         if ($cookie->getName(!= $name{
  351.             return false;
  352.         }
  353.         if ($host && $cookie->getHost(&& $cookie->isValidHost($host)) {
  354.             return false;
  355.         }
  356.         if ($cookie->isValidPath($path)) {
  357.             return false;
  358.         }
  359.         return true;
  360.     }
  361.     
  362.     /**
  363.      *    Uses a URL to sift relevant cookies by host and
  364.      *    path. Results are list of strings of form "name=value".
  365.      *    @param SimpleUrl $url       Url to select by.
  366.      *    @return array               Valid name and value pairs.
  367.      *    @access public
  368.      */
  369.     function selectAsPairs($url{
  370.         $pairs array();
  371.         foreach ($this->_cookies as $cookie{
  372.             if ($this->_isMatch($cookie$url->getHost()$url->getPath()$cookie->getName())) {
  373.                 $pairs[$cookie->getName('=' $cookie->getValue();
  374.             }
  375.         }
  376.         return $pairs;
  377.     }
  378. }
  379. ?>

Documentation generated on Sun, 04 May 2008 09:21:23 -0500 by phpDocumentor 1.3.0