diff options
author | carl <> | 2007-08-04 16:21:24 +0000 |
---|---|---|
committer | carl <> | 2007-08-04 16:21:24 +0000 |
commit | 8c964555633510dd85def6836f4b720366dce5ef (patch) | |
tree | 8cff91d456e1ce3e196cb045dca23f8ea717fe50 /framework/Web/THttpRequest.php | |
parent | 6875b48357e96b98a3c21794bb553ffad83ed0ab (diff) |
Fixed #672
Diffstat (limited to 'framework/Web/THttpRequest.php')
-rw-r--r-- | framework/Web/THttpRequest.php | 2437 |
1 files changed, 1225 insertions, 1212 deletions
diff --git a/framework/Web/THttpRequest.php b/framework/Web/THttpRequest.php index ef0660cc..bc3f9912 100644 --- a/framework/Web/THttpRequest.php +++ b/framework/Web/THttpRequest.php @@ -1,1213 +1,1226 @@ -<?php
-/**
- * THttpRequest, THttpCookie, THttpCookieCollection, TUri class file
- *
- * @author Qiang Xue <qiang.xue@gmail.com>
- * @link http://www.pradosoft.com/
- * @copyright Copyright © 2005 PradoSoft
- * @license http://www.pradosoft.com/license/
- * @version $Id$
- * @package System.Web
- */
-
-Prado::using('System.Web.TUrlManager');
-
-/**
- * THttpRequest class
- *
- * THttpRequest provides storage and access scheme for user request sent via HTTP.
- * It also encapsulates a uniform way to parse and construct URLs.
- *
- * User post data can be retrieved from THttpRequest by using it like an associative array.
- * For example, to test if a user supplies a variable named 'param1', you can use,
- * <code>
- * if(isset($request['param1'])) ...
- * // equivalent to:
- * // if($request->contains('param1')) ...
- * </code>
- * To get the value of 'param1', use,
- * <code>
- * $value=$request['param1'];
- * // equivalent to:
- * // $value=$request->itemAt('param1');
- * </code>
- * To traverse the user post data, use
- * <code>
- * foreach($request as $name=>$value) ...
- * </code>
- * Note, POST and GET variables are merged together in THttpRequest.
- * If a variable name appears in both POST and GET data, then POST data
- * takes precedence.
- *
- * To construct a URL that can be recognized by Prado, use {@link constructUrl()}.
- * The format of the recognizable URLs is determined according to
- * {@link setUrlManager UrlManager}. By default, the following two formats
- * are recognized:
- * <code>
- * /index.php?ServiceID=ServiceParameter&Name1=Value1&Name2=Value2
- * /index.php/ServiceID,ServiceParameter/Name1,Value1/Name2,Value2
- * </code>
- * The first format is called 'Get' while the second 'Path', which is specified
- * via {@link setUrlFormat UrlFormat}. For advanced users who want to use
- * their own URL formats, they can write customized URL management modules
- * and install the managers as application modules and set {@link setUrlManager UrlManager}.
- *
- * The ServiceID in the above URLs is as defined in the application configuration
- * (e.g. the default page service's service ID is 'page').
- * As a consequence, your GET variable names should not conflict with the service
- * IDs that your application supports.
- *
- * THttpRequest also provides the cookies sent by the user, user information such
- * as his browser capabilities, accepted languages, etc.
- *
- * By default, THttpRequest is registered with {@link TApplication} as the
- * request module. It can be accessed via {@link TApplication::getRequest()}.
- *
- * @author Qiang Xue <qiang.xue@gmail.com>
- * @version $Id$
- * @package System.Web
- * @since 3.0
- */
-class THttpRequest extends TApplicationComponent implements IteratorAggregate,ArrayAccess,Countable,IModule
-{
- /**
- * @var TUrlManager the URL manager module
- */
- private $_urlManager=null;
- /**
- * @var string the ID of the URL manager module
- */
- private $_urlManagerID='';
- /**
- * @var string Separator used to separate GET variable name and value when URL format is Path.
- */
- private $_separator=',';
- /**
- * @var string requested service ID
- */
- private $_serviceID=null;
- /**
- * @var string requested service parameter
- */
- private $_serviceParam=null;
- /**
- * @var THttpCookieCollection cookies sent from user
- */
- private $_cookies=null;
- /**
- * @var string requested URI (URL w/o host info)
- */
- private $_requestUri;
- /**
- * @var string path info of URL
- */
- private $_pathInfo;
- /**
- * @var boolean whether the session ID should be kept in cookie only
- */
- private $_cookieOnly=false;
- private $_urlFormat=THttpRequestUrlFormat::Get;
- private $_services;
- private $_requestResolved=false;
- private $_enableCookieValidation=false;
- /**
- * @var string request URL
- */
- private $_url=null;
-
- /**
- * @var string module id
- */
- private $_id;
-
- /**
- * @var array contains all request variables
- */
- private $_items=array();
-
- /**
- * @return string id of this module
- */
- public function getID()
- {
- return $this->_id;
- }
-
- /**
- * @param string id of this module
- */
- public function setID($value)
- {
- $this->_id=$value;
- }
-
- /**
- * Initializes the module.
- * This method is required by IModule and is invoked by application.
- * @param TXmlElement module configuration
- */
- public function init($config)
- {
- if(empty($this->_urlManagerID))
- {
- $this->_urlManager=new TUrlManager;
- $this->_urlManager->init(null);
- }
- else
- {
- $this->_urlManager=$this->getApplication()->getModule($this->_urlManagerID);
- if($this->_urlManager===null)
- throw new TConfigurationException('httprequest_urlmanager_inexist',$this->_urlManagerID);
- if(!($this->_urlManager instanceof TUrlManager))
- throw new TConfigurationException('httprequest_urlmanager_invalid',$this->_urlManagerID);
- }
-
- // Fill in default request info when the script is run in command line
- if(php_sapi_name()==='cli')
- {
- $_SERVER['REMOTE_ADDR']='127.0.0.1';
- $_SERVER['REQUEST_METHOD']='GET';
- $_SERVER['SERVER_NAME']='localhost';
- $_SERVER['SERVER_PORT']=80;
- $_SERVER['HTTP_USER_AGENT']='';
- }
-
- $this->_cookieOnly=(int)ini_get('session.use_cookies') && (int)ini_get('session.use_only_cookies');
-
- // Info about server variables:
- // PHP_SELF contains real URI (w/ path info, w/o query string)
- // SCRIPT_NAME is the real URI for the requested script (w/o path info and query string)
- // QUERY_STRING is the string following the '?' in the ur (eg the a=x part in http://foo/bar?a=x)
- // REQUEST_URI contains the URI part entered in the browser address bar
- // SCRIPT_FILENAME is the file path to the executing script
- if(isset($_SERVER['REQUEST_URI']))
- $this->_requestUri=$_SERVER['REQUEST_URI'];
- else // TBD: in this case, SCRIPT_NAME need to be escaped
- $this->_requestUri=$_SERVER['SCRIPT_NAME'].(empty($_SERVER['QUERY_STRING'])?'':'?'.$_SERVER['QUERY_STRING']);
-
- if(isset($_SERVER['PATH_INFO']))
- $this->_pathInfo=$_SERVER['PATH_INFO'];
- else if(strpos($_SERVER['PHP_SELF'],$_SERVER['SCRIPT_NAME'])===0)
- $this->_pathInfo=substr($_SERVER['PHP_SELF'],strlen($_SERVER['SCRIPT_NAME']));
- else
- $this->_pathInfo='';
-
- if(get_magic_quotes_gpc())
- {
- if(isset($_GET))
- $_GET=$this->stripSlashes($_GET);
- if(isset($_POST))
- $_POST=$this->stripSlashes($_POST);
- if(isset($_REQUEST))
- $_REQUEST=$this->stripSlashes($_REQUEST);
- if(isset($_COOKIE))
- $_COOKIE=$this->stripSlashes($_COOKIE);
- }
-
- $this->getApplication()->setRequest($this);
- }
-
- /**
- * Strips slashes from input data.
- * This method is applied when magic quotes is enabled.
- * @param mixed input data to be processed
- * @return mixed processed data
- */
- public function stripSlashes(&$data)
- {
- return is_array($data)?array_map(array($this,'stripSlashes'),$data):stripslashes($data);
- }
-
- /**
- * @return TUri the request URL
- */
- public function getUrl()
- {
- if($this->_url===null)
- {
- $secure=$this->getIsSecureConnection();
- $url=$secure?'https://':'http://';
- if(empty($_SERVER['HTTP_HOST']))
- {
- $url.=$_SERVER['SERVER_NAME'];
- $port=$_SERVER['SERVER_PORT'];
- if(($port!=80 && !$secure) || ($port!=443 && $secure))
- $url.=':'.$port;
- }
- else
- $url.=$_SERVER['HTTP_HOST'];
- $url.=$this->getRequestUri();
- $this->_url=new TUri($url);
- }
- return $this->_url;
- }
-
- /**
- * @return string the ID of the URL manager module
- */
- public function getUrlManager()
- {
- return $this->_urlManagerID;
- }
-
- /**
- * Sets the URL manager module.
- * By default, {@link TUrlManager} is used for managing URLs.
- * You may specify a different module for URL managing tasks
- * by loading it as an application module and setting this property
- * with the module ID.
- * @param string the ID of the URL manager module
- */
- public function setUrlManager($value)
- {
- $this->_urlManagerID=$value;
- }
-
- /**
- * @return TUrlManager the URL manager module
- */
- public function getUrlManagerModule()
- {
- return $this->_urlManager;
- }
-
- /**
- * @return THttpRequestUrlFormat the format of URLs. Defaults to THttpRequestUrlFormat::Get.
- */
- public function getUrlFormat()
- {
- return $this->_urlFormat;
- }
-
- /**
- * Sets the format of URLs constructed and interpretted by the request module.
- * A Get URL format is like index.php?name1=value1&name2=value2
- * while a Path URL format is like index.php/name1,value1/name2,value.
- * Changing the UrlFormat will affect {@link constructUrl} and how GET variables
- * are parsed.
- * @param THttpRequestUrlFormat the format of URLs.
- */
- public function setUrlFormat($value)
- {
- $this->_urlFormat=TPropertyValue::ensureEnum($value,'THttpRequestUrlFormat');
- }
-
- /**
- * @return string separator used to separate GET variable name and value when URL format is Path. Defaults to comma ','.
- */
- public function getUrlParamSeparator()
- {
- return $this->_separator;
- }
-
- /**
- * @param string separator used to separate GET variable name and value when URL format is Path.
- * @throws TInvalidDataValueException if the separator is not a single character
- */
- public function setUrlParamSeparator($value)
- {
- if(strlen($value)===1)
- $this->_separator=$value;
- else
- throw new TInvalidDataValueException('httprequest_separator_invalid');
- }
-
- /**
- * @return string request type, can be GET, POST, HEAD, or PUT
- */
- public function getRequestType()
- {
- return $_SERVER['REQUEST_METHOD'];
- }
-
- /**
- * @return boolean if the request is sent via secure channel (https)
- */
- public function getIsSecureConnection()
- {
- return isset($_SERVER['HTTPS']) && strcasecmp($_SERVER['HTTPS'],'off');
- }
-
- /**
- * @return string part of the request URL after script name and before question mark.
- */
- public function getPathInfo()
- {
- return $this->_pathInfo;
- }
-
- /**
- * @return string part of that request URL after the question mark
- */
- public function getQueryString()
- {
- return isset($_SERVER['QUERY_STRING'])?$_SERVER['QUERY_STRING']:'';
- }
-
- /**
- * @return string part of that request URL after the host info (including pathinfo and query string)
- */
- public function getRequestUri()
- {
- return $this->_requestUri;
- }
-
- /**
- * @return string schema and hostname of the requested URL
- */
- public function getBaseUrl()
- {
- return ($this->getIsSecureConnection() ? "https://" : "http://") . $_SERVER ['HTTP_HOST'];
- }
-
- /**
- * @return string entry script URL (w/o host part)
- */
- public function getApplicationUrl()
- {
- return $_SERVER['SCRIPT_NAME'];
- }
-
- /**
- * @return string entry script URL (w/ host part)
- */
- public function getAbsoluteApplicationUrl()
- {
- return $this->getBaseUrl() . $this->getApplicationUrl();
- }
-
- /**
- * @return string application entry script file path (processed w/ realpath())
- */
- public function getApplicationFilePath()
- {
- return realpath($_SERVER['SCRIPT_FILENAME']);
- }
-
- /**
- * @return string server name
- */
- public function getServerName()
- {
- return $_SERVER['SERVER_NAME'];
- }
-
- /**
- * @return integer server port number
- */
- public function getServerPort()
- {
- return $_SERVER['SERVER_PORT'];
- }
-
- /**
- * @return string URL referrer, null if not present
- */
- public function getUrlReferrer()
- {
- return isset($_SERVER['HTTP_REFERER'])?$_SERVER['HTTP_REFERER']:null;
- }
-
- /**
- * @return array user browser capabilities
- * @see get_browser
- */
- public function getBrowser()
- {
- return get_browser();
- }
-
- /**
- * @return string user agent
- */
- public function getUserAgent()
- {
- return $_SERVER['HTTP_USER_AGENT'];
- }
-
- /**
- * @return string user IP address
- */
- public function getUserHostAddress()
- {
- return $_SERVER['REMOTE_ADDR'];
- }
-
- /**
- * @return string user host name, null if cannot be determined
- */
- public function getUserHost()
- {
- return isset($_SERVER['REMOTE_HOST'])?$_SERVER['REMOTE_HOST']:null;
- }
-
- /**
- * @return string user browser accept types
- */
- public function getAcceptTypes()
- {
- // TBD: break it into array??
- return $_SERVER['HTTP_ACCEPT'];
- }
-
- /**
- * Returns a list of user preferred languages.
- * The languages are returned as an array. Each array element
- * represents a single language preference. The languages are ordered
- * according to user preferences. The first language is the most preferred.
- * @return array list of user preferred languages.
- */
- public function getUserLanguages()
- {
- return Prado::getUserLanguages();
- }
-
- /**
- * @return boolean whether cookies should be validated. Defaults to false.
- */
- public function getEnableCookieValidation()
- {
- return $this->_enableCookieValidation;
- }
-
- /**
- * @param boolean whether cookies should be validated.
- */
- public function setEnableCookieValidation($value)
- {
- $this->_enableCookieValidation=TPropertyValue::ensureBoolean($value);
- }
-
- /**
- * @return THttpCookieCollection list of cookies to be sent
- */
- public function getCookies()
- {
- if($this->_cookies===null)
- {
- $this->_cookies=new THttpCookieCollection;
- if($this->getEnableCookieValidation())
- {
- $sm=$this->getApplication()->getSecurityManager();
- foreach($_COOKIE as $key=>$value)
- {
- if(($value=$sm->validateData($value))!==false)
- $this->_cookies->add(new THttpCookie($key,$value));
- }
- }
- else
- {
- foreach($_COOKIE as $key=>$value)
- $this->_cookies->add(new THttpCookie($key,$value));
- }
- }
- return $this->_cookies;
- }
-
- /**
- * @return array list of uploaded files.
- */
- public function getUploadedFiles()
- {
- return $_FILES;
- }
-
- /**
- * @return array list of server variables.
- */
- public function getServerVariables()
- {
- return $_SERVER;
- }
-
- /**
- * @return array list of environment variables.
- */
- public function getEnvironmentVariables()
- {
- return $_ENV;
- }
-
- /**
- * Constructs a URL that can be recognized by PRADO.
- * The actual construction work is done by the URL manager module.
- * This method may append session information to the generated URL if needed.
- * You may provide your own URL manager module by setting {@link setUrlManager UrlManager}
- * to provide your own URL scheme.
- * @param string service ID
- * @param string service parameter
- * @param array GET parameters, null if not needed
- * @param boolean whether to encode the ampersand in URL, defaults to true.
- * @param boolean whether to encode the GET parameters (their names and values), defaults to false.
- * @return string URL
- * @see TUrlManager::constructUrl
- */
- public function constructUrl($serviceID,$serviceParam,$getItems=null,$encodeAmpersand=true,$encodeGetItems=true)
- {
- $url=$this->_urlManager->constructUrl($serviceID,$serviceParam,$getItems,$encodeAmpersand,$encodeGetItems);
- if(defined('SID') && SID != '' && !$this->_cookieOnly)
- return $url . (strpos($url,'?')===false? '?' : ($encodeAmpersand?'&':'&')) . SID;
- else
- return $url;
- }
-
- /**
- * Parses the request URL and returns an array of input parameters (excluding GET variables).
- * You may override this method to support customized URL format.
- * @return array list of input parameters, indexed by parameter names
- * @see TUrlManager::parseUrl
- */
- protected function parseUrl()
- {
- return $this->_urlManager->parseUrl();
- }
-
- /**
- * Resolves the requested service.
- * This method implements a URL-based service resolution.
- * A URL in the format of /index.php?sp=serviceID.serviceParameter
- * will be resolved with the serviceID and the serviceParameter.
- * You may override this method to provide your own way of service resolution.
- * @param array list of valid service IDs
- * @return string the currently requested service ID, null if no service ID is found
- * @see constructUrl
- */
- public function resolveRequest($serviceIDs)
- {
- Prado::trace("Resolving request from ".$_SERVER['REMOTE_ADDR'],'System.Web.THttpRequest');
- $this->_items=array_merge($_GET,$this->parseUrl(),$_POST);
- $this->_requestResolved=true;
- foreach($serviceIDs as $serviceID)
- {
- if($this->contains($serviceID))
- {
- $this->setServiceID($serviceID);
- $this->setServiceParameter($this->itemAt($serviceID));
- return $serviceID;
- }
- }
- return null;
- }
-
- /**
- * @return boolean true if request is already resolved, false otherwise.
- */
- public function getRequestResolved()
- {
- return $this->_requestResolved;
- }
-
- /**
- * @return string requested service ID
- */
- public function getServiceID()
- {
- return $this->_serviceID;
- }
-
- /**
- * Sets the requested service ID.
- * @param string requested service ID
- */
- public function setServiceID($value)
- {
- $this->_serviceID=$value;
- }
-
- /**
- * @return string requested service parameter
- */
- public function getServiceParameter()
- {
- return $this->_serviceParam;
- }
-
- /**
- * Sets the requested service parameter.
- * @param string requested service parameter
- */
- public function setServiceParameter($value)
- {
- $this->_serviceParam=$value;
- }
-
- //------ The following methods enable THttpRequest to be TMap-like -----
-
- /**
- * Returns an iterator for traversing the items in the list.
- * This method is required by the interface IteratorAggregate.
- * @return Iterator an iterator for traversing the items in the list.
- */
- public function getIterator()
- {
- return new TMapIterator($this->_items);
- }
-
- /**
- * @return integer the number of items in the request
- */
- public function getCount()
- {
- return count($this->_items);
- }
-
- /**
- * Returns the number of items in the request.
- * This method is required by Countable interface.
- * @return integer number of items in the request.
- */
- public function count()
- {
- return $this->getCount();
- }
-
- /**
- * @return array the key list
- */
- public function getKeys()
- {
- return array_keys($this->_items);
- }
-
- /**
- * Returns the item with the specified key.
- * This method is exactly the same as {@link offsetGet}.
- * @param mixed the key
- * @return mixed the element at the offset, null if no element is found at the offset
- */
- public function itemAt($key)
- {
- return isset($this->_items[$key]) ? $this->_items[$key] : null;
- }
-
- /**
- * Adds an item into the request.
- * Note, if the specified key already exists, the old value will be overwritten.
- * @param mixed key
- * @param mixed value
- */
- public function add($key,$value)
- {
- $this->_items[$key]=$value;
- }
-
- /**
- * Removes an item from the request by its key.
- * @param mixed the key of the item to be removed
- * @return mixed the removed value, null if no such key exists.
- * @throws TInvalidOperationException if the item cannot be removed
- */
- public function remove($key)
- {
- if(isset($this->_items[$key]) || array_key_exists($key,$this->_items))
- {
- $value=$this->_items[$key];
- unset($this->_items[$key]);
- return $value;
- }
- else
- return null;
- }
-
- /**
- * Removes all items in the request.
- */
- public function clear()
- {
- foreach(array_keys($this->_items) as $key)
- $this->remove($key);
- }
-
- /**
- * @param mixed the key
- * @return boolean whether the request contains an item with the specified key
- */
- public function contains($key)
- {
- return isset($this->_items[$key]) || array_key_exists($key,$this->_items);
- }
-
- /**
- * @return array the list of items in array
- */
- public function toArray()
- {
- return $this->_items;
- }
-
- /**
- * Returns whether there is an element at the specified offset.
- * This method is required by the interface ArrayAccess.
- * @param mixed the offset to check on
- * @return boolean
- */
- public function offsetExists($offset)
- {
- return $this->contains($offset);
- }
-
- /**
- * Returns the element at the specified offset.
- * This method is required by the interface ArrayAccess.
- * @param integer the offset to retrieve element.
- * @return mixed the element at the offset, null if no element is found at the offset
- */
- public function offsetGet($offset)
- {
- return $this->itemAt($offset);
- }
-
- /**
- * Sets the element at the specified offset.
- * This method is required by the interface ArrayAccess.
- * @param integer the offset to set element
- * @param mixed the element value
- */
- public function offsetSet($offset,$item)
- {
- $this->add($offset,$item);
- }
-
- /**
- * Unsets the element at the specified offset.
- * This method is required by the interface ArrayAccess.
- * @param mixed the offset to unset element
- */
- public function offsetUnset($offset)
- {
- $this->remove($offset);
- }
-}
-
-/**
- * THttpCookieCollection class.
- *
- * THttpCookieCollection implements a collection class to store cookies.
- * Besides using all functionalities from {@link TList}, you can also
- * retrieve a cookie by its name using either {@link findCookieByName} or
- * simply:
- * <code>
- * $cookie=$collection[$cookieName];
- * </code>
- *
- * @author Qiang Xue <qiang.xue@gmail.com>
- * @version $Id$
- * @package System.Web
- * @since 3.0
- */
-class THttpCookieCollection extends TList
-{
- /**
- * @var mixed owner of this collection
- */
- private $_o;
-
- /**
- * Constructor.
- * @param mixed owner of this collection.
- */
- public function __construct($owner=null)
- {
- $this->_o=$owner;
- }
-
- /**
- * Inserts an item at the specified position.
- * This overrides the parent implementation by performing additional
- * operations for each newly added THttpCookie object.
- * @param integer the specified position.
- * @param mixed new item
- * @throws TInvalidDataTypeException if the item to be inserted is not a THttpCookie object.
- */
- public function insertAt($index,$item)
- {
- if($item instanceof THttpCookie)
- {
- parent::insertAt($index,$item);
- if($this->_o instanceof THttpResponse)
- $this->_o->addCookie($item);
- }
- else
- throw new TInvalidDataTypeException('httpcookiecollection_httpcookie_required');
- }
-
- /**
- * Removes an item at the specified position.
- * This overrides the parent implementation by performing additional
- * cleanup work when removing a TCookie object.
- * @param integer the index of the item to be removed.
- * @return mixed the removed item.
- */
- public function removeAt($index)
- {
- $item=parent::removeAt($index);
- if($this->_o instanceof THttpResponse)
- $this->_o->removeCookie($item);
- return $item;
- }
-
- /**
- * @param integer|string index of the cookie in the collection or the cookie's name
- * @return THttpCookie the cookie found
- */
- public function itemAt($index)
- {
- if(is_integer($index))
- return parent::itemAt($index);
- else
- return $this->findCookieByName($index);
- }
-
- /**
- * Finds the cookie with the specified name.
- * @param string the name of the cookie to be looked for
- * @return THttpCookie the cookie, null if not found
- */
- public function findCookieByName($name)
- {
- foreach($this as $cookie)
- if($cookie->getName()===$name)
- return $cookie;
- return null;
- }
-}
-
-/**
- * THttpCookie class.
- *
- * A THttpCookie instance stores a single cookie, including the cookie name, value,
- * domain, path, expire, and secure.
- *
- * @author Qiang Xue <qiang.xue@gmail.com>
- * @version $Id$
- * @package System.Web
- * @since 3.0
- */
-class THttpCookie extends TComponent
-{
- /**
- * @var string domain of the cookie
- */
- private $_domain='';
- /**
- * @var string name of the cookie
- */
- private $_name;
- /**
- * @var string value of the cookie
- */
- private $_value=0;
- /**
- * @var integer expire of the cookie
- */
- private $_expire=0;
- /**
- * @var string path of the cookie
- */
- private $_path='/';
- /**
- * @var boolean whether cookie should be sent via secure connection
- */
- private $_secure=false;
-
- /**
- * Constructor.
- * @param string name of this cookie
- * @param string value of this cookie
- */
- public function __construct($name,$value)
- {
- $this->_name=$name;
- $this->_value=$value;
- }
-
- /**
- * @return string the domain to associate the cookie with
- */
- public function getDomain()
- {
- return $this->_domain;
- }
-
- /**
- * @param string the domain to associate the cookie with
- */
- public function setDomain($value)
- {
- $this->_domain=$value;
- }
-
- /**
- * @return integer the time the cookie expires. This is a Unix timestamp so is in number of seconds since the epoch.
- */
- public function getExpire()
- {
- return $this->_expire;
- }
-
- /**
- * @param integer the time the cookie expires. This is a Unix timestamp so is in number of seconds since the epoch.
- */
- public function setExpire($value)
- {
- $this->_expire=TPropertyValue::ensureInteger($value);
- }
-
- /**
- * @return string the name of the cookie
- */
- public function getName()
- {
- return $this->_name;
- }
-
- /**
- * @param string the name of the cookie
- */
- public function setName($value)
- {
- $this->_name=$value;
- }
-
- /**
- * @return string the value of the cookie
- */
- public function getValue()
- {
- return $this->_value;
- }
-
- /**
- * @param string the value of the cookie
- */
- public function setValue($value)
- {
- $this->_value=$value;
- }
-
- /**
- * @return string the path on the server in which the cookie will be available on, default is '/'
- */
- public function getPath()
- {
- return $this->_path;
- }
-
- /**
- * @param string the path on the server in which the cookie will be available on
- */
- public function setPath($value)
- {
- $this->_path=$value;
- }
-
- /**
- * @return boolean whether the cookie should only be transmitted over a secure HTTPS connection
- */
- public function getSecure()
- {
- return $this->_secure;
- }
-
- /**
- * @param boolean ether the cookie should only be transmitted over a secure HTTPS connection
- */
- public function setSecure($value)
- {
- $this->_secure=TPropertyValue::ensureBoolean($value);
- }
-}
-
-/**
- * TUri class
- *
- * TUri represents a URI. Given a URI
- * http://joe:whatever@example.com:8080/path/to/script.php?param=value#anchor
- * it will be decomposed as follows,
- * - scheme: http
- * - host: example.com
- * - port: 8080
- * - user: joe
- * - password: whatever
- * - path: /path/to/script.php
- * - query: param=value
- * - fragment: anchor
- *
- * @author Qiang Xue <qiang.xue@gmail.com>
- * @version $Id$
- * @package System.Web
- * @since 3.0
- */
-class TUri extends TComponent
-{
- /**
- * @var array list of default ports for known schemes
- */
- private static $_defaultPort=array(
- 'ftp'=>21,
- 'gopher'=>70,
- 'http'=>80,
- 'https'=>443,
- 'news'=>119,
- 'nntp'=>119,
- 'wais'=>210,
- 'telnet'=>23
- );
- /**
- * @var string scheme of the URI
- */
- private $_scheme;
- /**
- * @var string host name of the URI
- */
- private $_host;
- /**
- * @var integer port of the URI
- */
- private $_port;
- /**
- * @var string user of the URI
- */
- private $_user;
- /**
- * @var string password of the URI
- */
- private $_pass;
- /**
- * @var string path of the URI
- */
- private $_path;
- /**
- * @var string query string of the URI
- */
- private $_query;
- /**
- * @var string fragment of the URI
- */
- private $_fragment;
- /**
- * @var string the URI
- */
- private $_uri;
-
- /**
- * Constructor.
- * Decomposes the specified URI into parts.
- * @param string URI to be represented
- * @throws TInvalidDataValueException if URI is of bad format
- */
- public function __construct($uri)
- {
- if(($ret=@parse_url($uri))!==false)
- {
- // decoding???
- $this->_scheme=isset($ret['scheme'])?$ret['scheme']:'';
- $this->_host=isset($ret['host'])?$ret['host']:'';
- $this->_port=isset($ret['port'])?$ret['port']:'';
- $this->_user=isset($ret['user'])?$ret['user']:'';
- $this->_pass=isset($ret['pass'])?$ret['pass']:'';
- $this->_path=isset($ret['path'])?$ret['path']:'';
- $this->_query=isset($ret['query'])?$ret['query']:'';
- $this->_fragment=isset($ret['fragment'])?$ret['fragment']:'';
- $this->_uri=$uri;
- }
- else
- {
- throw new TInvalidDataValueException('uri_format_invalid',$uri);
- }
- }
-
- /**
- * @return string URI
- */
- public function getUri()
- {
- return $this->_uri;
- }
-
- /**
- * @return string scheme of the URI, such as 'http', 'https', 'ftp', etc.
- */
- public function getScheme()
- {
- return $this->_scheme;
- }
-
- /**
- * @return string hostname of the URI
- */
- public function getHost()
- {
- return $this->_host;
- }
-
- /**
- * @return integer port number of the URI
- */
- public function getPort()
- {
- return $this->_port;
- }
-
- /**
- * @return string username of the URI
- */
- public function getUser()
- {
- return $this->_user;
- }
-
- /**
- * @return string password of the URI
- */
- public function getPassword()
- {
- return $this->_pass;
- }
-
- /**
- * @return string path of the URI
- */
- public function getPath()
- {
- return $this->_path;
- }
-
- /**
- * @return string query string of the URI
- */
- public function getQuery()
- {
- return $this->_query;
- }
-
- /**
- * @return string fragment of the URI
- */
- public function getFragment()
- {
- return $this->_fragment;
- }
-}
-
-/**
- * THttpRequestUrlFormat class.
- * THttpRequestUrlFormat defines the enumerable type for the possible URL formats
- * that can be recognized by {@link THttpRequest}.
- *
- * The following enumerable values are defined:
- * - Get: the URL format is like /path/to/index.php?name1=value1&name2=value2...
- * - Path: the URL format is like /path/to/index.php/name1,value1/name2,value2...
- *
- * @author Qiang Xue <qiang.xue@gmail.com>
- * @version $Id$
- * @package System.Web
- * @since 3.0.4
- */
-class THttpRequestUrlFormat extends TEnumerable
-{
- const Get='Get';
- const Path='Path';
-}
-
+<?php +/** + * THttpRequest, THttpCookie, THttpCookieCollection, TUri class file + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005 PradoSoft + * @license http://www.pradosoft.com/license/ + * @version $Id$ + * @package System.Web + */ + +Prado::using('System.Web.TUrlManager'); + +/** + * THttpRequest class + * + * THttpRequest provides storage and access scheme for user request sent via HTTP. + * It also encapsulates a uniform way to parse and construct URLs. + * + * User post data can be retrieved from THttpRequest by using it like an associative array. + * For example, to test if a user supplies a variable named 'param1', you can use, + * <code> + * if(isset($request['param1'])) ... + * // equivalent to: + * // if($request->contains('param1')) ... + * </code> + * To get the value of 'param1', use, + * <code> + * $value=$request['param1']; + * // equivalent to: + * // $value=$request->itemAt('param1'); + * </code> + * To traverse the user post data, use + * <code> + * foreach($request as $name=>$value) ... + * </code> + * Note, POST and GET variables are merged together in THttpRequest. + * If a variable name appears in both POST and GET data, then POST data + * takes precedence. + * + * To construct a URL that can be recognized by Prado, use {@link constructUrl()}. + * The format of the recognizable URLs is determined according to + * {@link setUrlManager UrlManager}. By default, the following two formats + * are recognized: + * <code> + * /index.php?ServiceID=ServiceParameter&Name1=Value1&Name2=Value2 + * /index.php/ServiceID,ServiceParameter/Name1,Value1/Name2,Value2 + * </code> + * The first format is called 'Get' while the second 'Path', which is specified + * via {@link setUrlFormat UrlFormat}. For advanced users who want to use + * their own URL formats, they can write customized URL management modules + * and install the managers as application modules and set {@link setUrlManager UrlManager}. + * + * The ServiceID in the above URLs is as defined in the application configuration + * (e.g. the default page service's service ID is 'page'). + * As a consequence, your GET variable names should not conflict with the service + * IDs that your application supports. + * + * THttpRequest also provides the cookies sent by the user, user information such + * as his browser capabilities, accepted languages, etc. + * + * By default, THttpRequest is registered with {@link TApplication} as the + * request module. It can be accessed via {@link TApplication::getRequest()}. + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @version $Id$ + * @package System.Web + * @since 3.0 + */ +class THttpRequest extends TApplicationComponent implements IteratorAggregate,ArrayAccess,Countable,IModule +{ + /** + * @var TUrlManager the URL manager module + */ + private $_urlManager=null; + /** + * @var string the ID of the URL manager module + */ + private $_urlManagerID=''; + /** + * @var string Separator used to separate GET variable name and value when URL format is Path. + */ + private $_separator=','; + /** + * @var string requested service ID + */ + private $_serviceID=null; + /** + * @var string requested service parameter + */ + private $_serviceParam=null; + /** + * @var THttpCookieCollection cookies sent from user + */ + private $_cookies=null; + /** + * @var string requested URI (URL w/o host info) + */ + private $_requestUri; + /** + * @var string path info of URL + */ + private $_pathInfo; + /** + * @var boolean whether the session ID should be kept in cookie only + */ + private $_cookieOnly=false; + private $_urlFormat=THttpRequestUrlFormat::Get; + private $_services; + private $_requestResolved=false; + private $_enableCookieValidation=false; + private $_forceSecureConnection=null; + /** + * @var string request URL + */ + private $_url=null; + + /** + * @var string module id + */ + private $_id; + + /** + * @var array contains all request variables + */ + private $_items=array(); + + /** + * @return string id of this module + */ + public function getID() + { + return $this->_id; + } + + /** + * @param string id of this module + */ + public function setID($value) + { + $this->_id=$value; + } + + /** + * Initializes the module. + * This method is required by IModule and is invoked by application. + * @param TXmlElement module configuration + */ + public function init($config) + { + if(empty($this->_urlManagerID)) + { + $this->_urlManager=new TUrlManager; + $this->_urlManager->init(null); + } + else + { + $this->_urlManager=$this->getApplication()->getModule($this->_urlManagerID); + if($this->_urlManager===null) + throw new TConfigurationException('httprequest_urlmanager_inexist',$this->_urlManagerID); + if(!($this->_urlManager instanceof TUrlManager)) + throw new TConfigurationException('httprequest_urlmanager_invalid',$this->_urlManagerID); + } + + // Fill in default request info when the script is run in command line + if(php_sapi_name()==='cli') + { + $_SERVER['REMOTE_ADDR']='127.0.0.1'; + $_SERVER['REQUEST_METHOD']='GET'; + $_SERVER['SERVER_NAME']='localhost'; + $_SERVER['SERVER_PORT']=80; + $_SERVER['HTTP_USER_AGENT']=''; + } + + $this->_cookieOnly=(int)ini_get('session.use_cookies') && (int)ini_get('session.use_only_cookies'); + + // Info about server variables: + // PHP_SELF contains real URI (w/ path info, w/o query string) + // SCRIPT_NAME is the real URI for the requested script (w/o path info and query string) + // QUERY_STRING is the string following the '?' in the ur (eg the a=x part in http://foo/bar?a=x) + // REQUEST_URI contains the URI part entered in the browser address bar + // SCRIPT_FILENAME is the file path to the executing script + if(isset($_SERVER['REQUEST_URI'])) + $this->_requestUri=$_SERVER['REQUEST_URI']; + else // TBD: in this case, SCRIPT_NAME need to be escaped + $this->_requestUri=$_SERVER['SCRIPT_NAME'].(empty($_SERVER['QUERY_STRING'])?'':'?'.$_SERVER['QUERY_STRING']); + + if(isset($_SERVER['PATH_INFO'])) + $this->_pathInfo=$_SERVER['PATH_INFO']; + else if(strpos($_SERVER['PHP_SELF'],$_SERVER['SCRIPT_NAME'])===0) + $this->_pathInfo=substr($_SERVER['PHP_SELF'],strlen($_SERVER['SCRIPT_NAME'])); + else + $this->_pathInfo=''; + + if(get_magic_quotes_gpc()) + { + if(isset($_GET)) + $_GET=$this->stripSlashes($_GET); + if(isset($_POST)) + $_POST=$this->stripSlashes($_POST); + if(isset($_REQUEST)) + $_REQUEST=$this->stripSlashes($_REQUEST); + if(isset($_COOKIE)) + $_COOKIE=$this->stripSlashes($_COOKIE); + } + + $this->getApplication()->setRequest($this); + } + + /** + * Strips slashes from input data. + * This method is applied when magic quotes is enabled. + * @param mixed input data to be processed + * @return mixed processed data + */ + public function stripSlashes(&$data) + { + return is_array($data)?array_map(array($this,'stripSlashes'),$data):stripslashes($data); + } + + /** + * @return TUri the request URL + */ + public function getUrl() + { + if($this->_url===null) + { + $secure=$this->getIsSecureConnection(); + $url=$secure?'https://':'http://'; + if(empty($_SERVER['HTTP_HOST'])) + { + $url.=$_SERVER['SERVER_NAME']; + $port=$_SERVER['SERVER_PORT']; + if(($port!=80 && !$secure) || ($port!=443 && $secure)) + $url.=':'.$port; + } + else + $url.=$_SERVER['HTTP_HOST']; + $url.=$this->getRequestUri(); + $this->_url=new TUri($url); + } + return $this->_url; + } + + /** + * @return string the ID of the URL manager module + */ + public function getUrlManager() + { + return $this->_urlManagerID; + } + + /** + * Sets the URL manager module. + * By default, {@link TUrlManager} is used for managing URLs. + * You may specify a different module for URL managing tasks + * by loading it as an application module and setting this property + * with the module ID. + * @param string the ID of the URL manager module + */ + public function setUrlManager($value) + { + $this->_urlManagerID=$value; + } + + /** + * @return TUrlManager the URL manager module + */ + public function getUrlManagerModule() + { + return $this->_urlManager; + } + + /** + * @return THttpRequestUrlFormat the format of URLs. Defaults to THttpRequestUrlFormat::Get. + */ + public function getUrlFormat() + { + return $this->_urlFormat; + } + + /** + * Sets the format of URLs constructed and interpretted by the request module. + * A Get URL format is like index.php?name1=value1&name2=value2 + * while a Path URL format is like index.php/name1,value1/name2,value. + * Changing the UrlFormat will affect {@link constructUrl} and how GET variables + * are parsed. + * @param THttpRequestUrlFormat the format of URLs. + */ + public function setUrlFormat($value) + { + $this->_urlFormat=TPropertyValue::ensureEnum($value,'THttpRequestUrlFormat'); + } + + /** + * @return string separator used to separate GET variable name and value when URL format is Path. Defaults to comma ','. + */ + public function getUrlParamSeparator() + { + return $this->_separator; + } + + /** + * @param string separator used to separate GET variable name and value when URL format is Path. + * @throws TInvalidDataValueException if the separator is not a single character + */ + public function setUrlParamSeparator($value) + { + if(strlen($value)===1) + $this->_separator=$value; + else + throw new TInvalidDataValueException('httprequest_separator_invalid'); + } + + /** + * @return string request type, can be GET, POST, HEAD, or PUT + */ + public function getRequestType() + { + return $_SERVER['REQUEST_METHOD']; + } + + public function setForceSecureConnection($value) + { + $this->_forceSecureConnection=TPropertyValue::ensureBoolean($value); + } + + public function getForceSecureConnection() + { + return $this->_forceSecureConnection; + } + + /** + * @return boolean if the request is sent via secure channel (https) + */ + public function getIsSecureConnection() + { + return isset($_SERVER['HTTPS']) && strcasecmp($_SERVER['HTTPS'],'off'); + } + + /** + * @return string part of the request URL after script name and before question mark. + */ + public function getPathInfo() + { + return $this->_pathInfo; + } + + /** + * @return string part of that request URL after the question mark + */ + public function getQueryString() + { + return isset($_SERVER['QUERY_STRING'])?$_SERVER['QUERY_STRING']:''; + } + + /** + * @return string part of that request URL after the host info (including pathinfo and query string) + */ + public function getRequestUri() + { + return $this->_requestUri; + } + + /** + * @return string schema and hostname of the requested URL + */ + public function getBaseUrl() + { + return ($this->getIsSecureConnection() || $this->getForceSecureConnection() ? "https://" : "http://") . $_SERVER ['HTTP_HOST']; + } + + /** + * @return string entry script URL (w/o host part) + */ + public function getApplicationUrl() + { + return $_SERVER['SCRIPT_NAME']; + } + + /** + * @return string entry script URL (w/ host part) + */ + public function getAbsoluteApplicationUrl() + { + return $this->getBaseUrl() . $this->getApplicationUrl(); + } + + /** + * @return string application entry script file path (processed w/ realpath()) + */ + public function getApplicationFilePath() + { + return realpath($_SERVER['SCRIPT_FILENAME']); + } + + /** + * @return string server name + */ + public function getServerName() + { + return $_SERVER['SERVER_NAME']; + } + + /** + * @return integer server port number + */ + public function getServerPort() + { + return $_SERVER['SERVER_PORT']; + } + + /** + * @return string URL referrer, null if not present + */ + public function getUrlReferrer() + { + return isset($_SERVER['HTTP_REFERER'])?$_SERVER['HTTP_REFERER']:null; + } + + /** + * @return array user browser capabilities + * @see get_browser + */ + public function getBrowser() + { + return get_browser(); + } + + /** + * @return string user agent + */ + public function getUserAgent() + { + return $_SERVER['HTTP_USER_AGENT']; + } + + /** + * @return string user IP address + */ + public function getUserHostAddress() + { + return $_SERVER['REMOTE_ADDR']; + } + + /** + * @return string user host name, null if cannot be determined + */ + public function getUserHost() + { + return isset($_SERVER['REMOTE_HOST'])?$_SERVER['REMOTE_HOST']:null; + } + + /** + * @return string user browser accept types + */ + public function getAcceptTypes() + { + // TBD: break it into array?? + return $_SERVER['HTTP_ACCEPT']; + } + + /** + * Returns a list of user preferred languages. + * The languages are returned as an array. Each array element + * represents a single language preference. The languages are ordered + * according to user preferences. The first language is the most preferred. + * @return array list of user preferred languages. + */ + public function getUserLanguages() + { + return Prado::getUserLanguages(); + } + + /** + * @return boolean whether cookies should be validated. Defaults to false. + */ + public function getEnableCookieValidation() + { + return $this->_enableCookieValidation; + } + + /** + * @param boolean whether cookies should be validated. + */ + public function setEnableCookieValidation($value) + { + $this->_enableCookieValidation=TPropertyValue::ensureBoolean($value); + } + + /** + * @return THttpCookieCollection list of cookies to be sent + */ + public function getCookies() + { + if($this->_cookies===null) + { + $this->_cookies=new THttpCookieCollection; + if($this->getEnableCookieValidation()) + { + $sm=$this->getApplication()->getSecurityManager(); + foreach($_COOKIE as $key=>$value) + { + if(($value=$sm->validateData($value))!==false) + $this->_cookies->add(new THttpCookie($key,$value)); + } + } + else + { + foreach($_COOKIE as $key=>$value) + $this->_cookies->add(new THttpCookie($key,$value)); + } + } + return $this->_cookies; + } + + /** + * @return array list of uploaded files. + */ + public function getUploadedFiles() + { + return $_FILES; + } + + /** + * @return array list of server variables. + */ + public function getServerVariables() + { + return $_SERVER; + } + + /** + * @return array list of environment variables. + */ + public function getEnvironmentVariables() + { + return $_ENV; + } + + /** + * Constructs a URL that can be recognized by PRADO. + * The actual construction work is done by the URL manager module. + * This method may append session information to the generated URL if needed. + * You may provide your own URL manager module by setting {@link setUrlManager UrlManager} + * to provide your own URL scheme. + * @param string service ID + * @param string service parameter + * @param array GET parameters, null if not needed + * @param boolean whether to encode the ampersand in URL, defaults to true. + * @param boolean whether to encode the GET parameters (their names and values), defaults to false. + * @return string URL + * @see TUrlManager::constructUrl + */ + public function constructUrl($serviceID,$serviceParam,$getItems=null,$encodeAmpersand=true,$encodeGetItems=true) + { + $url=$this->_urlManager->constructUrl($serviceID,$serviceParam,$getItems,$encodeAmpersand,$encodeGetItems); + if($this->getForceSecureConnection()!==null) + $url = $this->getBaseUrl().$url; + if(defined('SID') && SID != '' && !$this->_cookieOnly) + return $url . (strpos($url,'?')===false? '?' : ($encodeAmpersand?'&':'&')) . SID; + else + return $url; + } + + /** + * Parses the request URL and returns an array of input parameters (excluding GET variables). + * You may override this method to support customized URL format. + * @return array list of input parameters, indexed by parameter names + * @see TUrlManager::parseUrl + */ + protected function parseUrl() + { + return $this->_urlManager->parseUrl(); + } + + /** + * Resolves the requested service. + * This method implements a URL-based service resolution. + * A URL in the format of /index.php?sp=serviceID.serviceParameter + * will be resolved with the serviceID and the serviceParameter. + * You may override this method to provide your own way of service resolution. + * @param array list of valid service IDs + * @return string the currently requested service ID, null if no service ID is found + * @see constructUrl + */ + public function resolveRequest($serviceIDs) + { + Prado::trace("Resolving request from ".$_SERVER['REMOTE_ADDR'],'System.Web.THttpRequest'); + $this->_items=array_merge($_GET,$this->parseUrl(),$_POST); + $this->_requestResolved=true; + foreach($serviceIDs as $serviceID) + { + if($this->contains($serviceID)) + { + $this->setServiceID($serviceID); + $this->setServiceParameter($this->itemAt($serviceID)); + return $serviceID; + } + } + return null; + } + + /** + * @return boolean true if request is already resolved, false otherwise. + */ + public function getRequestResolved() + { + return $this->_requestResolved; + } + + /** + * @return string requested service ID + */ + public function getServiceID() + { + return $this->_serviceID; + } + + /** + * Sets the requested service ID. + * @param string requested service ID + */ + public function setServiceID($value) + { + $this->_serviceID=$value; + } + + /** + * @return string requested service parameter + */ + public function getServiceParameter() + { + return $this->_serviceParam; + } + + /** + * Sets the requested service parameter. + * @param string requested service parameter + */ + public function setServiceParameter($value) + { + $this->_serviceParam=$value; + } + + //------ The following methods enable THttpRequest to be TMap-like ----- + + /** + * Returns an iterator for traversing the items in the list. + * This method is required by the interface IteratorAggregate. + * @return Iterator an iterator for traversing the items in the list. + */ + public function getIterator() + { + return new TMapIterator($this->_items); + } + + /** + * @return integer the number of items in the request + */ + public function getCount() + { + return count($this->_items); + } + + /** + * Returns the number of items in the request. + * This method is required by Countable interface. + * @return integer number of items in the request. + */ + public function count() + { + return $this->getCount(); + } + + /** + * @return array the key list + */ + public function getKeys() + { + return array_keys($this->_items); + } + + /** + * Returns the item with the specified key. + * This method is exactly the same as {@link offsetGet}. + * @param mixed the key + * @return mixed the element at the offset, null if no element is found at the offset + */ + public function itemAt($key) + { + return isset($this->_items[$key]) ? $this->_items[$key] : null; + } + + /** + * Adds an item into the request. + * Note, if the specified key already exists, the old value will be overwritten. + * @param mixed key + * @param mixed value + */ + public function add($key,$value) + { + $this->_items[$key]=$value; + } + + /** + * Removes an item from the request by its key. + * @param mixed the key of the item to be removed + * @return mixed the removed value, null if no such key exists. + * @throws TInvalidOperationException if the item cannot be removed + */ + public function remove($key) + { + if(isset($this->_items[$key]) || array_key_exists($key,$this->_items)) + { + $value=$this->_items[$key]; + unset($this->_items[$key]); + return $value; + } + else + return null; + } + + /** + * Removes all items in the request. + */ + public function clear() + { + foreach(array_keys($this->_items) as $key) + $this->remove($key); + } + + /** + * @param mixed the key + * @return boolean whether the request contains an item with the specified key + */ + public function contains($key) + { + return isset($this->_items[$key]) || array_key_exists($key,$this->_items); + } + + /** + * @return array the list of items in array + */ + public function toArray() + { + return $this->_items; + } + + /** + * Returns whether there is an element at the specified offset. + * This method is required by the interface ArrayAccess. + * @param mixed the offset to check on + * @return boolean + */ + public function offsetExists($offset) + { + return $this->contains($offset); + } + + /** + * Returns the element at the specified offset. + * This method is required by the interface ArrayAccess. + * @param integer the offset to retrieve element. + * @return mixed the element at the offset, null if no element is found at the offset + */ + public function offsetGet($offset) + { + return $this->itemAt($offset); + } + + /** + * Sets the element at the specified offset. + * This method is required by the interface ArrayAccess. + * @param integer the offset to set element + * @param mixed the element value + */ + public function offsetSet($offset,$item) + { + $this->add($offset,$item); + } + + /** + * Unsets the element at the specified offset. + * This method is required by the interface ArrayAccess. + * @param mixed the offset to unset element + */ + public function offsetUnset($offset) + { + $this->remove($offset); + } +} + +/** + * THttpCookieCollection class. + * + * THttpCookieCollection implements a collection class to store cookies. + * Besides using all functionalities from {@link TList}, you can also + * retrieve a cookie by its name using either {@link findCookieByName} or + * simply: + * <code> + * $cookie=$collection[$cookieName]; + * </code> + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @version $Id$ + * @package System.Web + * @since 3.0 + */ +class THttpCookieCollection extends TList +{ + /** + * @var mixed owner of this collection + */ + private $_o; + + /** + * Constructor. + * @param mixed owner of this collection. + */ + public function __construct($owner=null) + { + $this->_o=$owner; + } + + /** + * Inserts an item at the specified position. + * This overrides the parent implementation by performing additional + * operations for each newly added THttpCookie object. + * @param integer the specified position. + * @param mixed new item + * @throws TInvalidDataTypeException if the item to be inserted is not a THttpCookie object. + */ + public function insertAt($index,$item) + { + if($item instanceof THttpCookie) + { + parent::insertAt($index,$item); + if($this->_o instanceof THttpResponse) + $this->_o->addCookie($item); + } + else + throw new TInvalidDataTypeException('httpcookiecollection_httpcookie_required'); + } + + /** + * Removes an item at the specified position. + * This overrides the parent implementation by performing additional + * cleanup work when removing a TCookie object. + * @param integer the index of the item to be removed. + * @return mixed the removed item. + */ + public function removeAt($index) + { + $item=parent::removeAt($index); + if($this->_o instanceof THttpResponse) + $this->_o->removeCookie($item); + return $item; + } + + /** + * @param integer|string index of the cookie in the collection or the cookie's name + * @return THttpCookie the cookie found + */ + public function itemAt($index) + { + if(is_integer($index)) + return parent::itemAt($index); + else + return $this->findCookieByName($index); + } + + /** + * Finds the cookie with the specified name. + * @param string the name of the cookie to be looked for + * @return THttpCookie the cookie, null if not found + */ + public function findCookieByName($name) + { + foreach($this as $cookie) + if($cookie->getName()===$name) + return $cookie; + return null; + } +} + +/** + * THttpCookie class. + * + * A THttpCookie instance stores a single cookie, including the cookie name, value, + * domain, path, expire, and secure. + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @version $Id$ + * @package System.Web + * @since 3.0 + */ +class THttpCookie extends TComponent +{ + /** + * @var string domain of the cookie + */ + private $_domain=''; + /** + * @var string name of the cookie + */ + private $_name; + /** + * @var string value of the cookie + */ + private $_value=0; + /** + * @var integer expire of the cookie + */ + private $_expire=0; + /** + * @var string path of the cookie + */ + private $_path='/'; + /** + * @var boolean whether cookie should be sent via secure connection + */ + private $_secure=false; + + /** + * Constructor. + * @param string name of this cookie + * @param string value of this cookie + */ + public function __construct($name,$value) + { + $this->_name=$name; + $this->_value=$value; + } + + /** + * @return string the domain to associate the cookie with + */ + public function getDomain() + { + return $this->_domain; + } + + /** + * @param string the domain to associate the cookie with + */ + public function setDomain($value) + { + $this->_domain=$value; + } + + /** + * @return integer the time the cookie expires. This is a Unix timestamp so is in number of seconds since the epoch. + */ + public function getExpire() + { + return $this->_expire; + } + + /** + * @param integer the time the cookie expires. This is a Unix timestamp so is in number of seconds since the epoch. + */ + public function setExpire($value) + { + $this->_expire=TPropertyValue::ensureInteger($value); + } + + /** + * @return string the name of the cookie + */ + public function getName() + { + return $this->_name; + } + + /** + * @param string the name of the cookie + */ + public function setName($value) + { + $this->_name=$value; + } + + /** + * @return string the value of the cookie + */ + public function getValue() + { + return $this->_value; + } + + /** + * @param string the value of the cookie + */ + public function setValue($value) + { + $this->_value=$value; + } + + /** + * @return string the path on the server in which the cookie will be available on, default is '/' + */ + public function getPath() + { + return $this->_path; + } + + /** + * @param string the path on the server in which the cookie will be available on + */ + public function setPath($value) + { + $this->_path=$value; + } + + /** + * @return boolean whether the cookie should only be transmitted over a secure HTTPS connection + */ + public function getSecure() + { + return $this->_secure; + } + + /** + * @param boolean ether the cookie should only be transmitted over a secure HTTPS connection + */ + public function setSecure($value) + { + $this->_secure=TPropertyValue::ensureBoolean($value); + } +} + +/** + * TUri class + * + * TUri represents a URI. Given a URI + * http://joe:whatever@example.com:8080/path/to/script.php?param=value#anchor + * it will be decomposed as follows, + * - scheme: http + * - host: example.com + * - port: 8080 + * - user: joe + * - password: whatever + * - path: /path/to/script.php + * - query: param=value + * - fragment: anchor + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @version $Id$ + * @package System.Web + * @since 3.0 + */ +class TUri extends TComponent +{ + /** + * @var array list of default ports for known schemes + */ + private static $_defaultPort=array( + 'ftp'=>21, + 'gopher'=>70, + 'http'=>80, + 'https'=>443, + 'news'=>119, + 'nntp'=>119, + 'wais'=>210, + 'telnet'=>23 + ); + /** + * @var string scheme of the URI + */ + private $_scheme; + /** + * @var string host name of the URI + */ + private $_host; + /** + * @var integer port of the URI + */ + private $_port; + /** + * @var string user of the URI + */ + private $_user; + /** + * @var string password of the URI + */ + private $_pass; + /** + * @var string path of the URI + */ + private $_path; + /** + * @var string query string of the URI + */ + private $_query; + /** + * @var string fragment of the URI + */ + private $_fragment; + /** + * @var string the URI + */ + private $_uri; + + /** + * Constructor. + * Decomposes the specified URI into parts. + * @param string URI to be represented + * @throws TInvalidDataValueException if URI is of bad format + */ + public function __construct($uri) + { + if(($ret=@parse_url($uri))!==false) + { + // decoding??? + $this->_scheme=isset($ret['scheme'])?$ret['scheme']:''; + $this->_host=isset($ret['host'])?$ret['host']:''; + $this->_port=isset($ret['port'])?$ret['port']:''; + $this->_user=isset($ret['user'])?$ret['user']:''; + $this->_pass=isset($ret['pass'])?$ret['pass']:''; + $this->_path=isset($ret['path'])?$ret['path']:''; + $this->_query=isset($ret['query'])?$ret['query']:''; + $this->_fragment=isset($ret['fragment'])?$ret['fragment']:''; + $this->_uri=$uri; + } + else + { + throw new TInvalidDataValueException('uri_format_invalid',$uri); + } + } + + /** + * @return string URI + */ + public function getUri() + { + return $this->_uri; + } + + /** + * @return string scheme of the URI, such as 'http', 'https', 'ftp', etc. + */ + public function getScheme() + { + return $this->_scheme; + } + + /** + * @return string hostname of the URI + */ + public function getHost() + { + return $this->_host; + } + + /** + * @return integer port number of the URI + */ + public function getPort() + { + return $this->_port; + } + + /** + * @return string username of the URI + */ + public function getUser() + { + return $this->_user; + } + + /** + * @return string password of the URI + */ + public function getPassword() + { + return $this->_pass; + } + + /** + * @return string path of the URI + */ + public function getPath() + { + return $this->_path; + } + + /** + * @return string query string of the URI + */ + public function getQuery() + { + return $this->_query; + } + + /** + * @return string fragment of the URI + */ + public function getFragment() + { + return $this->_fragment; + } +} + +/** + * THttpRequestUrlFormat class. + * THttpRequestUrlFormat defines the enumerable type for the possible URL formats + * that can be recognized by {@link THttpRequest}. + * + * The following enumerable values are defined: + * - Get: the URL format is like /path/to/index.php?name1=value1&name2=value2... + * - Path: the URL format is like /path/to/index.php/name1,value1/name2,value2... + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @version $Id$ + * @package System.Web + * @since 3.0.4 + */ +class THttpRequestUrlFormat extends TEnumerable +{ + const Get='Get'; + const Path='Path'; +} + ?>
\ No newline at end of file |