diff options
author | Fabio Bas <ctrlaltca@gmail.com> | 2015-01-20 22:16:10 +0100 |
---|---|---|
committer | Fabio Bas <ctrlaltca@gmail.com> | 2015-01-20 22:16:10 +0100 |
commit | ef4d964de440970b76ab48fcbd6748f43675efa3 (patch) | |
tree | a6a6ffa6d53ffaa12c2d5bd6f036e4c013481f26 /framework/Web | |
parent | 7254793d2bbe3f2f3d87d97172c54a54deea0a3a (diff) |
one class per file: framework/Web/*.php
Diffstat (limited to 'framework/Web')
-rw-r--r-- | framework/Web/THttpCookie.php | 175 | ||||
-rw-r--r-- | framework/Web/THttpCookieCollection.php | 102 | ||||
-rw-r--r-- | framework/Web/THttpRequest.php | 452 | ||||
-rw-r--r-- | framework/Web/THttpRequestUrlFormat.php | 31 | ||||
-rw-r--r-- | framework/Web/THttpSession.php | 110 | ||||
-rw-r--r-- | framework/Web/THttpSessionCookieMode.php | 32 | ||||
-rw-r--r-- | framework/Web/TSessionIterator.php | 95 | ||||
-rw-r--r-- | framework/Web/TUri.php | 181 | ||||
-rw-r--r-- | framework/Web/TUrlMapping.php | 650 | ||||
-rw-r--r-- | framework/Web/TUrlMappingPattern.php | 615 | ||||
-rw-r--r-- | framework/Web/TUrlMappingPatternSecureConnection.php | 53 |
11 files changed, 1287 insertions, 1209 deletions
diff --git a/framework/Web/THttpCookie.php b/framework/Web/THttpCookie.php new file mode 100644 index 00000000..d655ef52 --- /dev/null +++ b/framework/Web/THttpCookie.php @@ -0,0 +1,175 @@ +<?php +/** + * THttpRequest, THttpCookie, THttpCookieCollection, TUri class file + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2014 PradoSoft + * @license http://www.pradosoft.com/license/ + * @package System.Web + */ + +/** + * 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> + * @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=''; + /** + * @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; + /** + * @var boolean if true the cookie value will be unavailable to JavaScript + */ + private $_httpOnly=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 boolean if true the cookie value will be unavailable to JavaScript + */ + public function getHttpOnly() + { + return $this->_httpOnly; + } + + /** + * @param boolean $value if true the cookie value will be unavailable to JavaScript + */ + public function setHttpOnly($value) + { + $this->_httpOnly = TPropertyValue::ensureBoolean($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); + } +}
\ No newline at end of file diff --git a/framework/Web/THttpCookieCollection.php b/framework/Web/THttpCookieCollection.php new file mode 100644 index 00000000..685b32ef --- /dev/null +++ b/framework/Web/THttpCookieCollection.php @@ -0,0 +1,102 @@ +<?php +/** + * THttpRequest, THttpCookie, THttpCookieCollection, TUri class file + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2014 PradoSoft + * @license http://www.pradosoft.com/license/ + * @package System.Web + */ + +/** + * 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> + * @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; + } +}
\ No newline at end of file diff --git a/framework/Web/THttpRequest.php b/framework/Web/THttpRequest.php index 5d77ba60..72e7cdea 100644 --- a/framework/Web/THttpRequest.php +++ b/framework/Web/THttpRequest.php @@ -953,454 +953,4 @@ class THttpRequest extends TApplicationComponent implements IteratorAggregate,Ar { $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> - * @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> - * @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=''; - /** - * @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; - /** - * @var boolean if true the cookie value will be unavailable to JavaScript - */ - private $_httpOnly=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 boolean if true the cookie value will be unavailable to JavaScript - */ - public function getHttpOnly() - { - return $this->_httpOnly; - } - - /** - * @param boolean $value if true the cookie value will be unavailable to JavaScript - */ - public function setHttpOnly($value) - { - $this->_httpOnly = TPropertyValue::ensureBoolean($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> - * @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... - * - HiddenPath: the URL format is like /path/to/name1,value1/name2,value2... - * - * @author Qiang Xue <qiang.xue@gmail.com> - * @package System.Web - * @since 3.0.4 - */ -class THttpRequestUrlFormat extends TEnumerable -{ - const Get='Get'; - const Path='Path'; - const HiddenPath='HiddenPath'; -} - +}
\ No newline at end of file diff --git a/framework/Web/THttpRequestUrlFormat.php b/framework/Web/THttpRequestUrlFormat.php new file mode 100644 index 00000000..80144c04 --- /dev/null +++ b/framework/Web/THttpRequestUrlFormat.php @@ -0,0 +1,31 @@ +<?php +/** + * THttpRequest, THttpCookie, THttpCookieCollection, TUri class file + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2014 PradoSoft + * @license http://www.pradosoft.com/license/ + * @package System.Web + */ + +/** + * 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... + * - HiddenPath: the URL format is like /path/to/name1,value1/name2,value2... + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @package System.Web + * @since 3.0.4 + */ +class THttpRequestUrlFormat extends TEnumerable +{ + const Get='Get'; + const Path='Path'; + const HiddenPath='HiddenPath'; +}
\ No newline at end of file diff --git a/framework/Web/THttpSession.php b/framework/Web/THttpSession.php index 6a2a3977..4b75c98f 100644 --- a/framework/Web/THttpSession.php +++ b/framework/Web/THttpSession.php @@ -626,112 +626,4 @@ class THttpSession extends TApplicationComponent implements IteratorAggregate,Ar { unset($_SESSION[$offset]); } -} - -/** - * TSessionIterator class - * - * TSessionIterator implements Iterator interface. - * - * TSessionIterator is used by THttpSession. It allows THttpSession to return a new iterator - * for traversing the session variables. - * - * @author Qiang Xue <qiang.xue@gmail.com> - * @package System.Web - * @since 3.0 - */ -class TSessionIterator implements Iterator -{ - /** - * @var array list of keys in the map - */ - private $_keys; - /** - * @var mixed current key - */ - private $_key; - - /** - * Constructor. - * @param array the data to be iterated through - */ - public function __construct() - { - $this->_keys=array_keys($_SESSION); - } - - /** - * Rewinds internal array pointer. - * This method is required by the interface Iterator. - */ - public function rewind() - { - $this->_key=reset($this->_keys); - } - - /** - * Returns the key of the current array element. - * This method is required by the interface Iterator. - * @return mixed the key of the current array element - */ - public function key() - { - return $this->_key; - } - - /** - * Returns the current array element. - * This method is required by the interface Iterator. - * @return mixed the current array element - */ - public function current() - { - return isset($_SESSION[$this->_key])?$_SESSION[$this->_key]:null; - } - - /** - * Moves the internal pointer to the next array element. - * This method is required by the interface Iterator. - */ - public function next() - { - do - { - $this->_key=next($this->_keys); - } - while(!isset($_SESSION[$this->_key]) && $this->_key!==false); - } - - /** - * Returns whether there is an element at current position. - * This method is required by the interface Iterator. - * @return boolean - */ - public function valid() - { - return $this->_key!==false; - } -} - - -/** - * THttpSessionCookieMode class. - * THttpSessionCookieMode defines the enumerable type for the possible methods of - * using cookies to store session ID. - * - * The following enumerable values are defined: - * - None: not using cookie. - * - Allow: using cookie. - * - Only: using cookie only. - * - * @author Qiang Xue <qiang.xue@gmail.com> - * @package System.Web - * @since 3.0.4 - */ -class THttpSessionCookieMode extends TEnumerable -{ - const None='None'; - const Allow='Allow'; - const Only='Only'; -} - +}
\ No newline at end of file diff --git a/framework/Web/THttpSessionCookieMode.php b/framework/Web/THttpSessionCookieMode.php new file mode 100644 index 00000000..810931b7 --- /dev/null +++ b/framework/Web/THttpSessionCookieMode.php @@ -0,0 +1,32 @@ +<?php +/** + * THttpSession class + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2014 PradoSoft + * @license http://www.pradosoft.com/license/ + * @package System.Web + */ + + +/** + * THttpSessionCookieMode class. + * THttpSessionCookieMode defines the enumerable type for the possible methods of + * using cookies to store session ID. + * + * The following enumerable values are defined: + * - None: not using cookie. + * - Allow: using cookie. + * - Only: using cookie only. + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @package System.Web + * @since 3.0.4 + */ +class THttpSessionCookieMode extends TEnumerable +{ + const None='None'; + const Allow='Allow'; + const Only='Only'; +}
\ No newline at end of file diff --git a/framework/Web/TSessionIterator.php b/framework/Web/TSessionIterator.php new file mode 100644 index 00000000..fab1dda2 --- /dev/null +++ b/framework/Web/TSessionIterator.php @@ -0,0 +1,95 @@ +<?php +/** + * THttpSession class + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2014 PradoSoft + * @license http://www.pradosoft.com/license/ + * @package System.Web + */ + +/** + * TSessionIterator class + * + * TSessionIterator implements Iterator interface. + * + * TSessionIterator is used by THttpSession. It allows THttpSession to return a new iterator + * for traversing the session variables. + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @package System.Web + * @since 3.0 + */ +class TSessionIterator implements Iterator +{ + /** + * @var array list of keys in the map + */ + private $_keys; + /** + * @var mixed current key + */ + private $_key; + + /** + * Constructor. + * @param array the data to be iterated through + */ + public function __construct() + { + $this->_keys=array_keys($_SESSION); + } + + /** + * Rewinds internal array pointer. + * This method is required by the interface Iterator. + */ + public function rewind() + { + $this->_key=reset($this->_keys); + } + + /** + * Returns the key of the current array element. + * This method is required by the interface Iterator. + * @return mixed the key of the current array element + */ + public function key() + { + return $this->_key; + } + + /** + * Returns the current array element. + * This method is required by the interface Iterator. + * @return mixed the current array element + */ + public function current() + { + return isset($_SESSION[$this->_key])?$_SESSION[$this->_key]:null; + } + + /** + * Moves the internal pointer to the next array element. + * This method is required by the interface Iterator. + */ + public function next() + { + do + { + $this->_key=next($this->_keys); + } + while(!isset($_SESSION[$this->_key]) && $this->_key!==false); + } + + /** + * Returns whether there is an element at current position. + * This method is required by the interface Iterator. + * @return boolean + */ + public function valid() + { + return $this->_key!==false; + } +}
\ No newline at end of file diff --git a/framework/Web/TUri.php b/framework/Web/TUri.php new file mode 100644 index 00000000..0e40d703 --- /dev/null +++ b/framework/Web/TUri.php @@ -0,0 +1,181 @@ +<?php +/** + * THttpRequest, THttpCookie, THttpCookieCollection, TUri class file + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2014 PradoSoft + * @license http://www.pradosoft.com/license/ + * @package System.Web + */ + +/** + * 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> + * @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; + } +}
\ No newline at end of file diff --git a/framework/Web/TUrlMapping.php b/framework/Web/TUrlMapping.php index d8ed75a8..862a39e5 100644 --- a/framework/Web/TUrlMapping.php +++ b/framework/Web/TUrlMapping.php @@ -384,652 +384,4 @@ class TUrlMapping extends TUrlManager { return $this->_matched; } -} - -/** - * TUrlMappingPattern class. - * - * TUrlMappingPattern represents a pattern used to parse and construct URLs. - * If the currently requested URL matches the pattern, it will alter - * the THttpRequest parameters. If a constructUrl() call matches the pattern - * parameters, the pattern will generate a valid URL. In both case, only the PATH_INFO - * part of a URL is parsed/constructed using the pattern. - * - * To specify the pattern, set the {@link setPattern Pattern} property. - * {@link setPattern Pattern} takes a string expression with - * parameter names enclosed between a left brace '{' and a right brace '}'. - * The patterns for each parameter can be set using {@link getParameters Parameters} - * attribute collection. For example - * <code> - * <url ... pattern="articles/{year}/{month}/{day}" - * parameters.year="\d{4}" parameters.month="\d{2}" parameters.day="\d+" /> - * </code> - * - * In the above example, the pattern contains 3 parameters named "year", - * "month" and "day". The pattern for these parameters are, respectively, - * "\d{4}" (4 digits), "\d{2}" (2 digits) and "\d+" (1 or more digits). - * Essentially, the <tt>Parameters</tt> attribute name and values are used - * as substrings in replacing the placeholders in the <tt>Pattern</tt> string - * to form a complete regular expression string. - * - * For more complicated patterns, one may specify the pattern using a regular expression - * by {@link setRegularExpression RegularExpression}. For example, the above pattern - * is equivalent to the following regular expression-based pattern: - * <code> - * #^articles/(?P<year>\d{4})/(?P<month>\d{2})\/(?P<day>\d+)$#u - * </code> - * The above regular expression used the "named group" feature available in PHP. - * If you intended to use the <tt>RegularExpression</tt> property or - * regular expressions in CDATA sections, notice that you need to escape the slash, - * if you are using the slash as regular expressions delimiter. - * - * Thus, only an url that matches the pattern will be valid. For example, - * a URL <tt>http://example.com/index.php/articles/2006/07/21</tt> will match the above pattern, - * while <tt>http://example.com/index.php/articles/2006/07/hello</tt> will not - * since the "day" parameter pattern is not satisfied. - * - * The parameter values are available through the <tt>THttpRequest</tt> instance (e.g. - * <tt>$this->Request['year']</tt>). - * - * The {@link setServiceParameter ServiceParameter} and {@link setServiceID ServiceID} - * (the default ID is 'page') set the service parameter and service id respectively. - * - * Since 3.1.4 you can also use simplyfied wildcard patterns to match multiple - * ServiceParameters with a single rule. The pattern must contain the placeholder - * {*} for the ServiceParameter. For example - * - * <url ServiceParameter="adminpages.*" pattern="admin/{*}" /> - * - * This rule will match an URL like <tt>http://example.com/index.php/admin/edituser</tt> - * and resolve it to the page Application.pages.admin.edituser. The wildcard matching - * is non-recursive. That means you have to add a rule for every subdirectory you - * want to access pages in: - * - * <url ServiceParameter="adminpages.users.*" pattern="useradmin/{*}" /> - * - * It is still possible to define an explicit rule for a page in the wildcard path. - * This rule has to preceed the wildcard rule. - * - * You can also use parameters with wildcard patterns. The parameters are then - * available with every matching page: - * - * <url ServiceParameter="adminpages.*" pattern="admin/{*}/{id}" parameters.id="\d+" /> - * - * To enable automatic parameter encoding in a path format from wildcard patterns you can set - * {@setUrlFormat UrlFormat} to 'Path': - * - * <url ServiceParameter="adminpages.*" pattern="admin/{*}" UrlFormat="Path" /> - * - * This will create and parse URLs of the form - * <tt>.../index.php/admin/listuser/param1/value1/param2/value2</tt>. - * - * Use {@setUrlParamSeparator} to define another separator character between parameter - * name and value. Parameter/value pairs are always separated by a '/'. - * - * <url ServiceParameter="adminpages.*" pattern="admin/{*}" UrlFormat="Path" UrlParamSeparator="-" /> - * - * <tt>.../index.php/admin/listuser/param1-value1/param2-value2</tt>. - * - * Since 3.2.2 you can also add a list of "constants" parameters that can be used just - * like the original "parameters" parameters, except that the supplied value will be treated - * as a simple string constant instead of a regular expression. For example - * - * <url ServiceParameter="MyPage" pattern="/mypage/mypath/list/detail/{pageidx}" parameters.pageidx="\d+" constants.listtype="detailed"/> - * <url ServiceParameter="MyPage" pattern="/mypage/mypath/list/summary/{pageidx}" parameters.pageidx="\d+" constants.listtype="summarized"/> - * - * These rules, when matched by the actual request, will make the application see a "lisstype" parameter present - * (even through not supplied in the request) and equal to "detailed" or "summarized", depending on the friendly url matched. - * The constants is practically a table-based validation and translation of specified, fixed-set parameter values. - * - * @author Wei Zhuo <weizhuo[at]gmail[dot]com> - * @package System.Web - * @since 3.0.5 - */ -class TUrlMappingPattern extends TComponent -{ - /** - * @var string service parameter such as Page class name. - */ - private $_serviceParameter; - /** - * @var string service ID, default is 'page'. - */ - private $_serviceID='page'; - /** - * @var string url pattern to match. - */ - private $_pattern; - /** - * @var TAttributeCollection parameter regular expressions. - */ - private $_parameters; - /** - * @var TAttributeCollection of constant parameters. - */ - protected $_constants; - /** - * @var string regular expression pattern. - */ - private $_regexp=''; - - private $_customUrl=true; - - private $_manager; - - private $_caseSensitive=true; - - private $_isWildCardPattern=false; - - private $_urlFormat=THttpRequestUrlFormat::Get; - - private $_separator='/'; - - /** - * @var TUrlMappingPatternSecureConnection - * @since 3.2 - */ - private $_secureConnection = TUrlMappingPatternSecureConnection::Automatic; - - /** - * Constructor. - * @param TUrlManager the URL manager instance - */ - public function __construct(TUrlManager $manager) - { - $this->_manager=$manager; - } - - /** - * @return TUrlManager the URL manager instance - */ - public function getManager() - { - return $this->_manager; - } - - /** - * Initializes the pattern. - * @param TXmlElement configuration for this module. - * @throws TConfigurationException if service parameter is not specified - */ - public function init($config) - { - if($this->_serviceParameter===null) - throw new TConfigurationException('urlmappingpattern_serviceparameter_required', $this->getPattern()); - if(strpos($this->_serviceParameter,'*')!==false) - $this->_isWildCardPattern=true; - } - - /** - * Substitute the parameter key value pairs as named groupings - * in the regular expression matching pattern. - * @return string regular expression pattern with parameter subsitution - */ - protected function getParameterizedPattern() - { - $params=array(); - $values=array(); - if ($this->_parameters) - { - foreach($this->_parameters as $key=>$value) - { - $params[]='{'.$key.'}'; - $values[]='(?P<'.$key.'>'.$value.')'; - } - } - if ($this->getIsWildCardPattern()) - { - $params[]='{*}'; - // service parameter must not contain '=' and '/' - $values[]='(?P<'.$this->getServiceID().'>[^=/]+)'; - } - $params[]='/'; - $values[]='\\/'; - $regexp=str_replace($params,$values,trim($this->getPattern(),'/').'/'); - if ($this->_urlFormat===THttpRequestUrlFormat::Get) - $regexp='/^'.$regexp.'$/u'; - else - $regexp='/^'.$regexp.'(?P<urlparams>.*)$/u'; - - if(!$this->getCaseSensitive()) - $regexp.='i'; - return $regexp; - } - - /** - * @return string full regular expression mapping pattern - */ - public function getRegularExpression() - { - return $this->_regexp; - } - - /** - * @param string full regular expression mapping pattern. - */ - public function setRegularExpression($value) - { - $this->_regexp=$value; - } - - /** - * @return boolean whether the {@link getPattern Pattern} should be treated as case sensititve. Defaults to true. - */ - public function getCaseSensitive() - { - return $this->_caseSensitive; - } - - /** - * @param boolean whether the {@link getPattern Pattern} should be treated as case sensititve. - */ - public function setCaseSensitive($value) - { - $this->_caseSensitive=TPropertyValue::ensureBoolean($value); - } - - /** - * @param string service parameter, such as page class name. - */ - public function setServiceParameter($value) - { - $this->_serviceParameter=$value; - } - - /** - * @return string service parameter, such as page class name. - */ - public function getServiceParameter() - { - return $this->_serviceParameter; - } - - /** - * @param string service id to handle. - */ - public function setServiceID($value) - { - $this->_serviceID=$value; - } - - /** - * @return string service id. - */ - public function getServiceID() - { - return $this->_serviceID; - } - - /** - * @return string url pattern to match. Defaults to ''. - */ - public function getPattern() - { - return $this->_pattern; - } - - /** - * @param string url pattern to match. - */ - public function setPattern($value) - { - $this->_pattern = $value; - } - - /** - * @return TAttributeCollection parameter key value pairs. - */ - public function getParameters() - { - if (!$this->_parameters) - { - $this->_parameters=new TAttributeCollection; - $this->_parameters->setCaseSensitive(true); - } - return $this->_parameters; - } - - /** - * @param TAttributeCollection new parameter key value pairs. - */ - public function setParameters($value) - { - $this->_parameters=$value; - } - - /** - * @return TAttributeCollection constanst parameter key value pairs. - * @since 3.2.2 - */ - public function getConstants() - { - if (!$this->_constants) - { - $this->_constants = new TAttributeCollection; - $this->_constants->setCaseSensitive(true); - } - return $this->_constants; - } - - /** - * Uses URL pattern (or full regular expression if available) to - * match the given url path. - * @param THttpRequest the request module - * @return array matched parameters, empty if no matches. - */ - public function getPatternMatches($request) - { - $matches=array(); - if(($pattern=$this->getRegularExpression())!=='') - preg_match($pattern,$request->getPathInfo(),$matches); - else - preg_match($this->getParameterizedPattern(),trim($request->getPathInfo(),'/').'/',$matches); - - if($this->getIsWildCardPattern() && isset($matches[$this->_serviceID])) - $matches[$this->_serviceID]=str_replace('*',$matches[$this->_serviceID],$this->_serviceParameter); - - if (isset($matches['urlparams'])) - { - $params=explode('/',$matches['urlparams']); - if ($this->_separator==='/') - { - while($key=array_shift($params)) - $matches[$key]=($value=array_shift($params)) ? $value : ''; - } - else - { - array_pop($params); - foreach($params as $param) - { - list($key,$value)=explode($this->_separator,$param,2); - $matches[$key]=$value; - } - } - unset($matches['urlparams']); - } - - if(count($matches) > 0 && $this->_constants) - { - foreach($this->_constants->toArray() as $key=>$value) - $matches[$key] = $value; - } - - return $matches; - } - - /** - * Returns a value indicating whether to use this pattern to construct URL. - * @return boolean whether to enable custom constructUrl. Defaults to true. - * @since 3.1.1 - */ - public function getEnableCustomUrl() - { - return $this->_customUrl; - } - - /** - * Sets a value indicating whether to enable custom constructUrl using this pattern - * @param boolean whether to enable custom constructUrl. - */ - public function setEnableCustomUrl($value) - { - $this->_customUrl=TPropertyValue::ensureBoolean($value); - } - - /** - * @return boolean whether this pattern is a wildcard pattern - * @since 3.1.4 - */ - public function getIsWildCardPattern() { - return $this->_isWildCardPattern; - } - - /** - * @return THttpRequestUrlFormat the format of URLs. Defaults to THttpRequestUrlFormat::Get. - */ - public function getUrlFormat() - { - return $this->_urlFormat; - } - - /** - * Sets the format of URLs constructed and interpreted by this pattern. - * 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. - * The separating character between name and value can be configured with - * {@link setUrlParamSeparator} and defaults to '/'. - * Changing the UrlFormat will affect {@link constructUrl} and how GET variables - * are parsed. - * @param THttpRequestUrlFormat the format of URLs. - * @since 3.1.4 - */ - 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 slash '/'. - */ - 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 TUrlMappingPatternSecureConnection the SecureConnection behavior. Defaults to {@link TUrlMappingPatternSecureConnection::Automatic Automatic} - * @since 3.2 - */ - public function getSecureConnection() - { - return $this->_secureConnection; - } - - /** - * @param TUrlMappingPatternSecureConnection the SecureConnection behavior. - * @since 3.2 - */ - public function setSecureConnection($value) - { - $this->_secureConnection = TPropertyValue::ensureEnum($value, 'TUrlMappingPatternSecureConnection'); - } - - /** - * @param array list of GET items to be put in the constructed URL - * @return boolean whether this pattern IS the one for constructing the URL with the specified GET items. - * @since 3.1.1 - */ - public function supportCustomUrl($getItems) - { - if(!$this->_customUrl || $this->getPattern()===null) - return false; - if ($this->_parameters) - { - foreach($this->_parameters as $key=>$value) - { - if(!isset($getItems[$key])) - return false; - } - } - - if ($this->_constants) - { - foreach($this->_constants->toArray() as $key=>$value) - { - if (!isset($getItems[$key])) - return false; - if ($getItems[$key]!=$value) - return false; - } - } - return true; - } - - /** - * Constructs a URL using this pattern. - * @param array list of GET variables - * @param boolean whether the ampersand should be encoded in the constructed URL - * @param boolean whether the GET variables should be encoded in the constructed URL - * @return string the constructed URL - * @since 3.1.1 - */ - public function constructUrl($getItems,$encodeAmpersand,$encodeGetItems) - { - if ($this->_constants) - { - foreach($this->_constants->toArray() as $key=>$value) - { - unset($getItems[$key]); - } - } - - $extra=array(); - $replace=array(); - // for the GET variables matching the pattern, put them in the URL path - foreach($getItems as $key=>$value) - { - if(($this->_parameters && $this->_parameters->contains($key)) || ($key==='*' && $this->getIsWildCardPattern())) - $replace['{'.$key.'}']=$encodeGetItems ? rawurlencode($value) : $value; - else - $extra[$key]=$value; - } - - $url=$this->_manager->getUrlPrefix().'/'.ltrim(strtr($this->getPattern(),$replace),'/'); - - // for the rest of the GET variables, put them in the query string - if(count($extra)>0) - { - if ($this->_urlFormat===THttpRequestUrlFormat::Path && $this->getIsWildCardPattern()) { - foreach ($extra as $name=>$value) - $url.='/'.$name.$this->_separator.($encodeGetItems?rawurlencode($value):$value); - return $url; - } - - $url2=''; - $amp=$encodeAmpersand?'&':'&'; - if($encodeGetItems) - { - foreach($extra as $name=>$value) - { - if(is_array($value)) - { - $name=rawurlencode($name.'[]'); - foreach($value as $v) - $url2.=$amp.$name.'='.rawurlencode($v); - } - else - $url2.=$amp.rawurlencode($name).'='.rawurlencode($value); - } - } - else - { - foreach($extra as $name=>$value) - { - if(is_array($value)) - { - foreach($value as $v) - $url2.=$amp.$name.'[]='.$v; - } - else - $url2.=$amp.$name.'='.$value; - } - } - $url=$url.'?'.substr($url2,strlen($amp)); - } - return $this -> applySecureConnectionPrefix($url); - } - - /** - * Apply behavior of {@link SecureConnection} property by conditionaly prefixing - * URL with {@link THttpRequest::getBaseUrl()} - * - * @param string $url - * @return string - * @since 3.2 - */ - protected function applySecureConnectionPrefix($url) - { - static $request; - if($request === null) $request = Prado::getApplication() -> getRequest(); - - static $isSecureConnection; - if($isSecureConnection === null) $isSecureConnection = $request -> getIsSecureConnection(); - - switch($this -> getSecureConnection()) - { - case TUrlMappingPatternSecureConnection::EnableIfNotSecure: - if($isSecureConnection) return $url; - return $request -> getBaseUrl(true) . $url; - break; - case TUrlMappingPatternSecureConnection::DisableIfSecure: - if(!$isSecureConnection) return $url; - return $request -> getBaseUrl(false) . $url; - break; - case TUrlMappingPatternSecureConnection::Enable: - return $request -> getBaseUrl(true) . $url; - break; - case TUrlMappingPatternSecureConnection::Disable: - return $request -> getBaseUrl(false) . $url; - break; - case TUrlMappingPatternSecureConnection::Automatic: - default: - return $url; - break; - } - } -} - -/** - * TUrlMappingPatternSecureConnection class - * - * TUrlMappingPatternSecureConnection defines the enumerable type for the possible SecureConnection - * URL prefix behavior that can be used by {@link TUrlMappingPattern::constructUrl()}. - * - * @author Yves Berkholz <godzilla80[at]gmx[dot]net> - * @package System.Web - * @since 3.2 - */ -class TUrlMappingPatternSecureConnection extends TEnumerable -{ - /** - * Keep current SecureConnection status - * means no prefixing - */ - const Automatic = 'Automatic'; - - /** - * Force use secured connection - * always prefixing with https://example.com/path/to/app - */ - const Enable = 'Enable'; - - /** - * Force use unsecured connection - * always prefixing with http://example.com/path/to/app - */ - const Disable = 'Disable'; - - /** - * Force use secured connection, if in unsecured mode - * prefixing with https://example.com/path/to/app - */ - const EnableIfNotSecure = 'EnableIfNotSecure'; - - /** - * Force use unsecured connection, if in secured mode - * prefixing with https://example.com/path/to/app - */ - const DisableIfSecure = 'DisableIfSecure'; -} +}
\ No newline at end of file diff --git a/framework/Web/TUrlMappingPattern.php b/framework/Web/TUrlMappingPattern.php new file mode 100644 index 00000000..ec1dd7e6 --- /dev/null +++ b/framework/Web/TUrlMappingPattern.php @@ -0,0 +1,615 @@ +<?php +/** + * TUrlMapping, TUrlMappingPattern and TUrlMappingPatternSecureConnection class file. + * + * @author Wei Zhuo <weizhuo[at]gamil[dot]com> + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2014 PradoSoft + * @license http://www.pradosoft.com/license/ + * @package System.Web + */ + +/** + * TUrlMappingPattern class. + * + * TUrlMappingPattern represents a pattern used to parse and construct URLs. + * If the currently requested URL matches the pattern, it will alter + * the THttpRequest parameters. If a constructUrl() call matches the pattern + * parameters, the pattern will generate a valid URL. In both case, only the PATH_INFO + * part of a URL is parsed/constructed using the pattern. + * + * To specify the pattern, set the {@link setPattern Pattern} property. + * {@link setPattern Pattern} takes a string expression with + * parameter names enclosed between a left brace '{' and a right brace '}'. + * The patterns for each parameter can be set using {@link getParameters Parameters} + * attribute collection. For example + * <code> + * <url ... pattern="articles/{year}/{month}/{day}" + * parameters.year="\d{4}" parameters.month="\d{2}" parameters.day="\d+" /> + * </code> + * + * In the above example, the pattern contains 3 parameters named "year", + * "month" and "day". The pattern for these parameters are, respectively, + * "\d{4}" (4 digits), "\d{2}" (2 digits) and "\d+" (1 or more digits). + * Essentially, the <tt>Parameters</tt> attribute name and values are used + * as substrings in replacing the placeholders in the <tt>Pattern</tt> string + * to form a complete regular expression string. + * + * For more complicated patterns, one may specify the pattern using a regular expression + * by {@link setRegularExpression RegularExpression}. For example, the above pattern + * is equivalent to the following regular expression-based pattern: + * <code> + * #^articles/(?P<year>\d{4})/(?P<month>\d{2})\/(?P<day>\d+)$#u + * </code> + * The above regular expression used the "named group" feature available in PHP. + * If you intended to use the <tt>RegularExpression</tt> property or + * regular expressions in CDATA sections, notice that you need to escape the slash, + * if you are using the slash as regular expressions delimiter. + * + * Thus, only an url that matches the pattern will be valid. For example, + * a URL <tt>http://example.com/index.php/articles/2006/07/21</tt> will match the above pattern, + * while <tt>http://example.com/index.php/articles/2006/07/hello</tt> will not + * since the "day" parameter pattern is not satisfied. + * + * The parameter values are available through the <tt>THttpRequest</tt> instance (e.g. + * <tt>$this->Request['year']</tt>). + * + * The {@link setServiceParameter ServiceParameter} and {@link setServiceID ServiceID} + * (the default ID is 'page') set the service parameter and service id respectively. + * + * Since 3.1.4 you can also use simplyfied wildcard patterns to match multiple + * ServiceParameters with a single rule. The pattern must contain the placeholder + * {*} for the ServiceParameter. For example + * + * <url ServiceParameter="adminpages.*" pattern="admin/{*}" /> + * + * This rule will match an URL like <tt>http://example.com/index.php/admin/edituser</tt> + * and resolve it to the page Application.pages.admin.edituser. The wildcard matching + * is non-recursive. That means you have to add a rule for every subdirectory you + * want to access pages in: + * + * <url ServiceParameter="adminpages.users.*" pattern="useradmin/{*}" /> + * + * It is still possible to define an explicit rule for a page in the wildcard path. + * This rule has to preceed the wildcard rule. + * + * You can also use parameters with wildcard patterns. The parameters are then + * available with every matching page: + * + * <url ServiceParameter="adminpages.*" pattern="admin/{*}/{id}" parameters.id="\d+" /> + * + * To enable automatic parameter encoding in a path format from wildcard patterns you can set + * {@setUrlFormat UrlFormat} to 'Path': + * + * <url ServiceParameter="adminpages.*" pattern="admin/{*}" UrlFormat="Path" /> + * + * This will create and parse URLs of the form + * <tt>.../index.php/admin/listuser/param1/value1/param2/value2</tt>. + * + * Use {@setUrlParamSeparator} to define another separator character between parameter + * name and value. Parameter/value pairs are always separated by a '/'. + * + * <url ServiceParameter="adminpages.*" pattern="admin/{*}" UrlFormat="Path" UrlParamSeparator="-" /> + * + * <tt>.../index.php/admin/listuser/param1-value1/param2-value2</tt>. + * + * Since 3.2.2 you can also add a list of "constants" parameters that can be used just + * like the original "parameters" parameters, except that the supplied value will be treated + * as a simple string constant instead of a regular expression. For example + * + * <url ServiceParameter="MyPage" pattern="/mypage/mypath/list/detail/{pageidx}" parameters.pageidx="\d+" constants.listtype="detailed"/> + * <url ServiceParameter="MyPage" pattern="/mypage/mypath/list/summary/{pageidx}" parameters.pageidx="\d+" constants.listtype="summarized"/> + * + * These rules, when matched by the actual request, will make the application see a "lisstype" parameter present + * (even through not supplied in the request) and equal to "detailed" or "summarized", depending on the friendly url matched. + * The constants is practically a table-based validation and translation of specified, fixed-set parameter values. + * + * @author Wei Zhuo <weizhuo[at]gmail[dot]com> + * @package System.Web + * @since 3.0.5 + */ +class TUrlMappingPattern extends TComponent +{ + /** + * @var string service parameter such as Page class name. + */ + private $_serviceParameter; + /** + * @var string service ID, default is 'page'. + */ + private $_serviceID='page'; + /** + * @var string url pattern to match. + */ + private $_pattern; + /** + * @var TAttributeCollection parameter regular expressions. + */ + private $_parameters; + /** + * @var TAttributeCollection of constant parameters. + */ + protected $_constants; + /** + * @var string regular expression pattern. + */ + private $_regexp=''; + + private $_customUrl=true; + + private $_manager; + + private $_caseSensitive=true; + + private $_isWildCardPattern=false; + + private $_urlFormat=THttpRequestUrlFormat::Get; + + private $_separator='/'; + + /** + * @var TUrlMappingPatternSecureConnection + * @since 3.2 + */ + private $_secureConnection = TUrlMappingPatternSecureConnection::Automatic; + + /** + * Constructor. + * @param TUrlManager the URL manager instance + */ + public function __construct(TUrlManager $manager) + { + $this->_manager=$manager; + } + + /** + * @return TUrlManager the URL manager instance + */ + public function getManager() + { + return $this->_manager; + } + + /** + * Initializes the pattern. + * @param TXmlElement configuration for this module. + * @throws TConfigurationException if service parameter is not specified + */ + public function init($config) + { + if($this->_serviceParameter===null) + throw new TConfigurationException('urlmappingpattern_serviceparameter_required', $this->getPattern()); + if(strpos($this->_serviceParameter,'*')!==false) + $this->_isWildCardPattern=true; + } + + /** + * Substitute the parameter key value pairs as named groupings + * in the regular expression matching pattern. + * @return string regular expression pattern with parameter subsitution + */ + protected function getParameterizedPattern() + { + $params=array(); + $values=array(); + if ($this->_parameters) + { + foreach($this->_parameters as $key=>$value) + { + $params[]='{'.$key.'}'; + $values[]='(?P<'.$key.'>'.$value.')'; + } + } + if ($this->getIsWildCardPattern()) + { + $params[]='{*}'; + // service parameter must not contain '=' and '/' + $values[]='(?P<'.$this->getServiceID().'>[^=/]+)'; + } + $params[]='/'; + $values[]='\\/'; + $regexp=str_replace($params,$values,trim($this->getPattern(),'/').'/'); + if ($this->_urlFormat===THttpRequestUrlFormat::Get) + $regexp='/^'.$regexp.'$/u'; + else + $regexp='/^'.$regexp.'(?P<urlparams>.*)$/u'; + + if(!$this->getCaseSensitive()) + $regexp.='i'; + return $regexp; + } + + /** + * @return string full regular expression mapping pattern + */ + public function getRegularExpression() + { + return $this->_regexp; + } + + /** + * @param string full regular expression mapping pattern. + */ + public function setRegularExpression($value) + { + $this->_regexp=$value; + } + + /** + * @return boolean whether the {@link getPattern Pattern} should be treated as case sensititve. Defaults to true. + */ + public function getCaseSensitive() + { + return $this->_caseSensitive; + } + + /** + * @param boolean whether the {@link getPattern Pattern} should be treated as case sensititve. + */ + public function setCaseSensitive($value) + { + $this->_caseSensitive=TPropertyValue::ensureBoolean($value); + } + + /** + * @param string service parameter, such as page class name. + */ + public function setServiceParameter($value) + { + $this->_serviceParameter=$value; + } + + /** + * @return string service parameter, such as page class name. + */ + public function getServiceParameter() + { + return $this->_serviceParameter; + } + + /** + * @param string service id to handle. + */ + public function setServiceID($value) + { + $this->_serviceID=$value; + } + + /** + * @return string service id. + */ + public function getServiceID() + { + return $this->_serviceID; + } + + /** + * @return string url pattern to match. Defaults to ''. + */ + public function getPattern() + { + return $this->_pattern; + } + + /** + * @param string url pattern to match. + */ + public function setPattern($value) + { + $this->_pattern = $value; + } + + /** + * @return TAttributeCollection parameter key value pairs. + */ + public function getParameters() + { + if (!$this->_parameters) + { + $this->_parameters=new TAttributeCollection; + $this->_parameters->setCaseSensitive(true); + } + return $this->_parameters; + } + + /** + * @param TAttributeCollection new parameter key value pairs. + */ + public function setParameters($value) + { + $this->_parameters=$value; + } + + /** + * @return TAttributeCollection constanst parameter key value pairs. + * @since 3.2.2 + */ + public function getConstants() + { + if (!$this->_constants) + { + $this->_constants = new TAttributeCollection; + $this->_constants->setCaseSensitive(true); + } + return $this->_constants; + } + + /** + * Uses URL pattern (or full regular expression if available) to + * match the given url path. + * @param THttpRequest the request module + * @return array matched parameters, empty if no matches. + */ + public function getPatternMatches($request) + { + $matches=array(); + if(($pattern=$this->getRegularExpression())!=='') + preg_match($pattern,$request->getPathInfo(),$matches); + else + preg_match($this->getParameterizedPattern(),trim($request->getPathInfo(),'/').'/',$matches); + + if($this->getIsWildCardPattern() && isset($matches[$this->_serviceID])) + $matches[$this->_serviceID]=str_replace('*',$matches[$this->_serviceID],$this->_serviceParameter); + + if (isset($matches['urlparams'])) + { + $params=explode('/',$matches['urlparams']); + if ($this->_separator==='/') + { + while($key=array_shift($params)) + $matches[$key]=($value=array_shift($params)) ? $value : ''; + } + else + { + array_pop($params); + foreach($params as $param) + { + list($key,$value)=explode($this->_separator,$param,2); + $matches[$key]=$value; + } + } + unset($matches['urlparams']); + } + + if(count($matches) > 0 && $this->_constants) + { + foreach($this->_constants->toArray() as $key=>$value) + $matches[$key] = $value; + } + + return $matches; + } + + /** + * Returns a value indicating whether to use this pattern to construct URL. + * @return boolean whether to enable custom constructUrl. Defaults to true. + * @since 3.1.1 + */ + public function getEnableCustomUrl() + { + return $this->_customUrl; + } + + /** + * Sets a value indicating whether to enable custom constructUrl using this pattern + * @param boolean whether to enable custom constructUrl. + */ + public function setEnableCustomUrl($value) + { + $this->_customUrl=TPropertyValue::ensureBoolean($value); + } + + /** + * @return boolean whether this pattern is a wildcard pattern + * @since 3.1.4 + */ + public function getIsWildCardPattern() { + return $this->_isWildCardPattern; + } + + /** + * @return THttpRequestUrlFormat the format of URLs. Defaults to THttpRequestUrlFormat::Get. + */ + public function getUrlFormat() + { + return $this->_urlFormat; + } + + /** + * Sets the format of URLs constructed and interpreted by this pattern. + * 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. + * The separating character between name and value can be configured with + * {@link setUrlParamSeparator} and defaults to '/'. + * Changing the UrlFormat will affect {@link constructUrl} and how GET variables + * are parsed. + * @param THttpRequestUrlFormat the format of URLs. + * @since 3.1.4 + */ + 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 slash '/'. + */ + 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 TUrlMappingPatternSecureConnection the SecureConnection behavior. Defaults to {@link TUrlMappingPatternSecureConnection::Automatic Automatic} + * @since 3.2 + */ + public function getSecureConnection() + { + return $this->_secureConnection; + } + + /** + * @param TUrlMappingPatternSecureConnection the SecureConnection behavior. + * @since 3.2 + */ + public function setSecureConnection($value) + { + $this->_secureConnection = TPropertyValue::ensureEnum($value, 'TUrlMappingPatternSecureConnection'); + } + + /** + * @param array list of GET items to be put in the constructed URL + * @return boolean whether this pattern IS the one for constructing the URL with the specified GET items. + * @since 3.1.1 + */ + public function supportCustomUrl($getItems) + { + if(!$this->_customUrl || $this->getPattern()===null) + return false; + if ($this->_parameters) + { + foreach($this->_parameters as $key=>$value) + { + if(!isset($getItems[$key])) + return false; + } + } + + if ($this->_constants) + { + foreach($this->_constants->toArray() as $key=>$value) + { + if (!isset($getItems[$key])) + return false; + if ($getItems[$key]!=$value) + return false; + } + } + return true; + } + + /** + * Constructs a URL using this pattern. + * @param array list of GET variables + * @param boolean whether the ampersand should be encoded in the constructed URL + * @param boolean whether the GET variables should be encoded in the constructed URL + * @return string the constructed URL + * @since 3.1.1 + */ + public function constructUrl($getItems,$encodeAmpersand,$encodeGetItems) + { + if ($this->_constants) + { + foreach($this->_constants->toArray() as $key=>$value) + { + unset($getItems[$key]); + } + } + + $extra=array(); + $replace=array(); + // for the GET variables matching the pattern, put them in the URL path + foreach($getItems as $key=>$value) + { + if(($this->_parameters && $this->_parameters->contains($key)) || ($key==='*' && $this->getIsWildCardPattern())) + $replace['{'.$key.'}']=$encodeGetItems ? rawurlencode($value) : $value; + else + $extra[$key]=$value; + } + + $url=$this->_manager->getUrlPrefix().'/'.ltrim(strtr($this->getPattern(),$replace),'/'); + + // for the rest of the GET variables, put them in the query string + if(count($extra)>0) + { + if ($this->_urlFormat===THttpRequestUrlFormat::Path && $this->getIsWildCardPattern()) { + foreach ($extra as $name=>$value) + $url.='/'.$name.$this->_separator.($encodeGetItems?rawurlencode($value):$value); + return $url; + } + + $url2=''; + $amp=$encodeAmpersand?'&':'&'; + if($encodeGetItems) + { + foreach($extra as $name=>$value) + { + if(is_array($value)) + { + $name=rawurlencode($name.'[]'); + foreach($value as $v) + $url2.=$amp.$name.'='.rawurlencode($v); + } + else + $url2.=$amp.rawurlencode($name).'='.rawurlencode($value); + } + } + else + { + foreach($extra as $name=>$value) + { + if(is_array($value)) + { + foreach($value as $v) + $url2.=$amp.$name.'[]='.$v; + } + else + $url2.=$amp.$name.'='.$value; + } + } + $url=$url.'?'.substr($url2,strlen($amp)); + } + return $this -> applySecureConnectionPrefix($url); + } + + /** + * Apply behavior of {@link SecureConnection} property by conditionaly prefixing + * URL with {@link THttpRequest::getBaseUrl()} + * + * @param string $url + * @return string + * @since 3.2 + */ + protected function applySecureConnectionPrefix($url) + { + static $request; + if($request === null) $request = Prado::getApplication() -> getRequest(); + + static $isSecureConnection; + if($isSecureConnection === null) $isSecureConnection = $request -> getIsSecureConnection(); + + switch($this -> getSecureConnection()) + { + case TUrlMappingPatternSecureConnection::EnableIfNotSecure: + if($isSecureConnection) return $url; + return $request -> getBaseUrl(true) . $url; + break; + case TUrlMappingPatternSecureConnection::DisableIfSecure: + if(!$isSecureConnection) return $url; + return $request -> getBaseUrl(false) . $url; + break; + case TUrlMappingPatternSecureConnection::Enable: + return $request -> getBaseUrl(true) . $url; + break; + case TUrlMappingPatternSecureConnection::Disable: + return $request -> getBaseUrl(false) . $url; + break; + case TUrlMappingPatternSecureConnection::Automatic: + default: + return $url; + break; + } + } +}
\ No newline at end of file diff --git a/framework/Web/TUrlMappingPatternSecureConnection.php b/framework/Web/TUrlMappingPatternSecureConnection.php new file mode 100644 index 00000000..809eee0d --- /dev/null +++ b/framework/Web/TUrlMappingPatternSecureConnection.php @@ -0,0 +1,53 @@ +<?php +/** + * TUrlMapping, TUrlMappingPattern and TUrlMappingPatternSecureConnection class file. + * + * @author Wei Zhuo <weizhuo[at]gamil[dot]com> + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2014 PradoSoft + * @license http://www.pradosoft.com/license/ + * @package System.Web + */ + +/** + * TUrlMappingPatternSecureConnection class + * + * TUrlMappingPatternSecureConnection defines the enumerable type for the possible SecureConnection + * URL prefix behavior that can be used by {@link TUrlMappingPattern::constructUrl()}. + * + * @author Yves Berkholz <godzilla80[at]gmx[dot]net> + * @package System.Web + * @since 3.2 + */ +class TUrlMappingPatternSecureConnection extends TEnumerable +{ + /** + * Keep current SecureConnection status + * means no prefixing + */ + const Automatic = 'Automatic'; + + /** + * Force use secured connection + * always prefixing with https://example.com/path/to/app + */ + const Enable = 'Enable'; + + /** + * Force use unsecured connection + * always prefixing with http://example.com/path/to/app + */ + const Disable = 'Disable'; + + /** + * Force use secured connection, if in unsecured mode + * prefixing with https://example.com/path/to/app + */ + const EnableIfNotSecure = 'EnableIfNotSecure'; + + /** + * Force use unsecured connection, if in secured mode + * prefixing with https://example.com/path/to/app + */ + const DisableIfSecure = 'DisableIfSecure'; +}
\ No newline at end of file |