diff options
| author | GODZilla0480@gmail.com <> | 2011-10-17 07:36:47 +0000 | 
|---|---|---|
| committer | GODZilla0480@gmail.com <> | 2011-10-17 07:36:47 +0000 | 
| commit | 22471c977d4edc4ddfe63abe23928d03e659f045 (patch) | |
| tree | 363c6861ec66e705eb9289d4bcdbd1db3320fd94 | |
| parent | 9b0b7d32a4d7ab6d1bbd0f8ca14be9fbf325f081 (diff) | |
Port changes of r3050 (branches/3.1) to trunk
| -rw-r--r-- | HISTORY | 2 | ||||
| -rw-r--r-- | demos/quickstart/protected/pages/Configurations/UrlMapping.page | 71 | ||||
| -rw-r--r-- | framework/Web/TUrlMapping.php | 71 | 
3 files changed, 89 insertions, 55 deletions
@@ -33,6 +33,8 @@ ENH: Issue #356 - Added a new "Clickable" operating mode to TDatePicker (ctrlalt  BUG: Issue #361 - TActiveListBox multiple selection bug (ctrlaltca)  BUG: Issue #366 - Use divs instead of spans around tables in TActiveDataGrid (ctrlaltca)  BUG: Issue #365 - [Runtime Notice] Declaration of T${DriverName}MetaData::quoteTableName() should be compatible with that of TDbMetaData::quoteTableName() (Yves) +BUG: Issue #367 - Parameterized RegularExpression property in UrlMapping raise TPhpErrorException in DOMDocument::loadXML() (Yves) +ENH: Performance (micro)optimization in TUrlMapping::loadUrlMappings - invoke `getDefaultMappingClass` outside of loop (Yves)  Version 3.1.10 Jul 17, 2011  BUG: Added missing timeout on TCacheHttpSession (ctrlaltca) diff --git a/demos/quickstart/protected/pages/Configurations/UrlMapping.page b/demos/quickstart/protected/pages/Configurations/UrlMapping.page index c47ace28..4af61180 100644 --- a/demos/quickstart/protected/pages/Configurations/UrlMapping.page +++ b/demos/quickstart/protected/pages/Configurations/UrlMapping.page @@ -22,12 +22,12 @@ pattern will be replaced with the corresponding GET variable values.  To use <tt>TUrlMapping</tt>, one must set the <tt>UrlManager</tt> property of the <tt>THttpRequest</tt> module as the <tt>TUrlMapping</tt> module ID. See following for an example,
  <com:TTextHighlighter Language="xml" CssClass="source block-content" id="code_230098">
  <modules>
 -    <module id="request" class="THttpRequest" UrlManager="friendly-url" />
 -    <module id="friendly-url" class="System.Web.TUrlMapping">
 -        <url ServiceParameter="Posts.ViewPost" pattern="post/{id}/" parameters.id="\d+" />
 -        <url ServiceParameter="Posts.ListPost" pattern="archive/{time}/" parameters.time="\d{6}" />
 -        <url ServiceParameter="Posts.ListPost" pattern="category/{cat}/" parameters.cat="\d+" />
 -    </module>
 +		<module id="request" class="THttpRequest" UrlManager="friendly-url" />
 +		<module id="friendly-url" class="System.Web.TUrlMapping">
 +				<url ServiceParameter="Posts.ViewPost" pattern="post/{id}/" parameters.id="\d+" />
 +				<url ServiceParameter="Posts.ListPost" pattern="archive/{time}/" parameters.time="\d{6}" />
 +				<url ServiceParameter="Posts.ListPost" pattern="category/{cat}/" parameters.cat="\d+" />
 +		</module>
  </modules>
  </com:TTextHighlighter>
  </p>
 @@ -36,9 +36,9 @@ To use <tt>TUrlMapping</tt>, one must set the <tt>UrlManager</tt> property of th  The above example is part of the application configuration of the <tt>blog</tt> demo in the PRADO release. It enables recognition of the following URL formats:
  </p>
  <ul id="u1" class="block-content">
 -  <li><tt>/index.php/post/123</tt> is recognized as <tt>/index.php?page=Posts.ViewPost&id=123</tt></li>
 -  <li><tt>/index.php/archive/200605</tt> is recognized as <tt>/index.php?page=Posts.ListPost&time=200605</tt></li>
 -  <li><tt>/index.php/category/2</tt> is recognized as <tt>/index.php?page=Posts.ListPost&cat=2</tt></li>
 +	<li><tt>/index.php/post/123</tt> is recognized as <tt>/index.php?page=Posts.ViewPost&id=123</tt></li>
 +	<li><tt>/index.php/archive/200605</tt> is recognized as <tt>/index.php?page=Posts.ListPost&time=200605</tt></li>
 +	<li><tt>/index.php/category/2</tt> is recognized as <tt>/index.php?page=Posts.ListPost&cat=2</tt></li>
  </ul>
  <p id="230226" class="block-content">
 @@ -69,13 +69,14 @@ using <tt>Parameters</tt> attribute collection.  For example,
  <com:TTextHighlighter Language="xml" CssClass="source block-content" id="code_230099">
  <url ServiceParameter="ArticleView" pattern="articles/{year}/{month}/{day}"
 -     parameters.year="\d{4}" parameters.month="\d{2}" parameters.day="\d+" />
 +	parameters.year="\d{4}" parameters.month="\d{2}" parameters.day="\d+" />
  </com:TTextHighlighter>
  </p>
  The example is equivalent to the following regular expression (it uses the "named group" feature in regular expressions available in PHP):
  <com:TTextHighlighter Language="xml" CssClass="source block-content" id="code_230100">
 -<url ServiceParameter="ArticleView"
 -     RegularExpression="/articles\/(?P<year>\d{4})\/(?P<month>\d{2})\/(?P<day>\d+)/u" />
 +<url ServiceParameter="ArticleView"><![CDATA[
 +	#articles/(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d+)#u
 +]]></url>
  </com:TTextHighlighter>
  <p id="230229" class="block-content">
  In the above example, the pattern contains 3 parameters named "<tt>year</tt>",
 @@ -83,12 +84,22 @@ In the above example, the pattern contains 3 parameters named "<tt>year</tt>",  respectively, "<tt>\d{4}</tt>" (4 digits), "<tt>\d{2}</tt>" (2 digits)
  and "<tt>\d+</tt>" (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
 +as substrings in replacing the placeholders in the <tt>Pattern</tt> string
  to form a complete regular expression string.
  </p>
 -<div class="note"><b class="tip">Note:</b> If you intended to use the <tt>RegularExpression</tt>
 -property you need to escape the slash in regular expressions.
 +For simple (not parameterized) regular expressions you can use the <tt>RegularExpression</tt> property:
 +<com:TTextHighlighter Language="xml" CssClass="source block-content">
 +<url ServiceParameter="ArticleView"
 +	RegularExpression="/articles\/best-of/u" />
 +</com:TTextHighlighter>
 +
 +<div class="note"><b class="tip">Note:</b>
 +	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.
 +	<br/>
 +	If you are using the "<i>CDATA section</i>" version all whitespaces like
 +	<code>\n, \t, \r</code> and so on will be removed automaticly.
  </div>
  <p id="230230" class="block-content">Following from the above pattern example,
 @@ -107,11 +118,11 @@ object. For example, <tt>$this->Request['year']</tt>.  </p>
  <p id="230232" class="block-content">The URL mapping are evaluated in order they are placed and only the first pattern that matches
 - the URL will be used. Cascaded mapping can be achieved by placing the URL mappings
 - in particular order. For example, placing the most specific mappings first.
 +the URL will be used. Cascaded mapping can be achieved by placing the URL mappings
 +in particular order. For example, placing the most specific mappings first.
  </p>
 -<p class="block-content">Since version 3.1.4, Prado also provides wildcard patterns to use friendly URLs 
 +<p class="block-content">Since version 3.1.4, Prado also provides wildcard patterns to use friendly URLs
  for a bunch of pages in a directory with a single rule. Therefore you can use the <tt>{*}</tt> wildcard
  in your pattern to let Prado know, where to find the ServiceID in your request URL. You can also specify
  parameters with these patterns if a lot of pages share common parameters.</p>
 @@ -124,18 +135,18 @@ parameters with these patterns if a lot of pages share common parameters.</p>  <p class="block-content">With these rules, any of the following URLs will be recognized:
  <ul id="u1" class="block-content">
 -  <li><tt>/index.php/post/ViewPost/123</tt> is recognized as <tt>/index.php?page=Posts.ViewPost&id=123</tt></li>
 -  <li><tt>/index.php/post/ListPost/123</tt> is recognized as <tt>/index.php?page=Posts.ListPost&id=123</tt></li>
 -  <li><tt>/index.php/post/ListPost/123</tt> is recognized as <tt>/index.php?page=Posts.ListPost&id=123</tt></li>
 -  <li><tt>/index.php/post/MyPost</tt> is recognized as <tt>/index.php?page=Posts.MyPost</tt></li>
 -  <li><tt>/index.php/info/Conditions</tt> is recognized as <tt>/index.php?page=Static.Info.Conditions</tt></li>
 -  <li><tt>/index.php/info/About</tt> is recognized as <tt>/index.php?page=Static.Info.About</tt></li>
 +	<li><tt>/index.php/post/ViewPost/123</tt> is recognized as <tt>/index.php?page=Posts.ViewPost&id=123</tt></li>
 +	<li><tt>/index.php/post/ListPost/123</tt> is recognized as <tt>/index.php?page=Posts.ListPost&id=123</tt></li>
 +	<li><tt>/index.php/post/ListPost/123</tt> is recognized as <tt>/index.php?page=Posts.ListPost&id=123</tt></li>
 +	<li><tt>/index.php/post/MyPost</tt> is recognized as <tt>/index.php?page=Posts.MyPost</tt></li>
 +	<li><tt>/index.php/info/Conditions</tt> is recognized as <tt>/index.php?page=Static.Info.Conditions</tt></li>
 +	<li><tt>/index.php/info/About</tt> is recognized as <tt>/index.php?page=Static.Info.About</tt></li>
  </ul>
  </p>
  <p id="250001" class="block-content">As above, put more specific rules before more common rules as the first matching rule will be used.</p>
 -<p id="250002" class="block-content">To make configuration of friendly URLs for multiple pages even easier, you can also use <tt>UrlFormat="Path"</tt> 
 +<p id="250002" class="block-content">To make configuration of friendly URLs for multiple pages even easier, you can also use <tt>UrlFormat="Path"</tt>
  in combination with wildcard patterns. In fact, this feature only is available in combination with wildcard rules:</P>
  <com:TTextHighlighter Language="xml" CssClass="source block-content">
 @@ -143,13 +154,13 @@ in combination with wildcard patterns. In fact, this feature only is available i  <url ServiceParameter="*" pattern="{*}" UrlFormat="Path" />
  </com:TTextHighlighter>
 -<p class="block-content">Parameters will get appended to the specified patterns as name/value pairs, separated by a "/". 
 +<p class="block-content">Parameters will get appended to the specified patterns as name/value pairs, separated by a "/".
  (You can change the separator character with <tt>UrlParamSeparator</tt>.)
  <ul id="u1" class="block-content">
 -  <li><tt>/index.php/list/cat/15/month/12</tt> is recognized as <tt>/index.php?page=list&cat=15&month=12</tt></li>
 -  <li><tt>/index.php/edit/id/12</tt> is recognized as <tt>/index.php?page=list&id=12</tt></li>
 -  <li><tt>/index.php/show/name/foo</tt> is recognized as <tt>/index.php?page=show&name=foo</tt></li>
 -  <li><tt>/index.php/admin/edit/id/12</tt> is recognized as <tt>/index.php?page=user.admin.edit&id=12</tt></li>
 +	<li><tt>/index.php/list/cat/15/month/12</tt> is recognized as <tt>/index.php?page=list&cat=15&month=12</tt></li>
 +	<li><tt>/index.php/edit/id/12</tt> is recognized as <tt>/index.php?page=list&id=12</tt></li>
 +	<li><tt>/index.php/show/name/foo</tt> is recognized as <tt>/index.php?page=show&name=foo</tt></li>
 +	<li><tt>/index.php/admin/edit/id/12</tt> is recognized as <tt>/index.php?page=user.admin.edit&id=12</tt></li>
  </ul>
  </p>
 diff --git a/framework/Web/TUrlMapping.php b/framework/Web/TUrlMapping.php index 69abc7a9..5338c119 100644 --- a/framework/Web/TUrlMapping.php +++ b/framework/Web/TUrlMapping.php @@ -120,7 +120,7 @@ class TUrlMapping extends TUrlManager  	protected function loadConfigFile()
  	{
  		if(is_file($this->_configFile))
 - 		{
 +		{
  			if($this->getApplication()->getConfigurationType()==TApplication::CONFIG_TYPE_PHP)
  			{
  				$config = include $this->_configFile;
 @@ -227,6 +227,8 @@ class TUrlMapping extends TUrlManager  	 */
  	protected function loadUrlMappings($config)
  	{
 +		$defaultClass = $this->getDefaultMappingClass();
 +
  		if(is_array($config))
  		{
  			if(isset($config['urls']) && is_array($config['urls']))
 @@ -235,7 +237,7 @@ class TUrlMapping extends TUrlManager  				{
  					$class=null;
  					if(!isset($url['class']))
 -						$class=$this->getDefaultMappingClass();
 +						$class=$defaultClass;
  					$pattern=Prado::createComponent($class,$this);
  					$properties = isset($url['properties'])?$url['properties']:array();
  					$this->buildUrlMapping($class,$pattern,$properties,$url);
 @@ -248,7 +250,7 @@ class TUrlMapping extends TUrlManager  			{
  				$properties=$url->getAttributes();
  				if(($class=$properties->remove('class'))===null)
 -					$class=$this->getDefaultMappingClass();
 +					$class=$defaultClass;
  				$pattern=Prado::createComponent($class,$this);
  				$this->buildUrlMapping($class,$pattern,$properties,$url);
  			}
 @@ -262,6 +264,23 @@ class TUrlMapping extends TUrlManager  			throw new TConfigurationException('urlmapping_urlmappingpattern_required');
  		foreach($properties as $name=>$value)
  			$pattern->setSubproperty($name,$value);
 +
 +		if($url instanceof TXmlElement) {
 +			$text = $url -> getValue();
 +			if($text) {
 +				$text = preg_replace('/(\s+)/S', '', $text);
 +				if(($regExp = $pattern->getRegularExpression()) !== '')
 +				trigger_error(sPrintF('%s.RegularExpression property value "%s" for ServiceID="%s" and ServiceParameter="%s" was replaced by node value "%s"',
 +				get_class($pattern),
 +				$regExp,
 +				$pattern->getServiceID(),
 +				$pattern->getServiceParameter(),
 +				$text),
 +				E_USER_NOTICE);
 +				$pattern->setRegularExpression($text);
 +			}
 +		}
 +
  		$this->_patterns[]=$pattern;
  		$pattern->init($url);
 @@ -325,8 +344,8 @@ class TUrlMapping extends TUrlManager  	{
  		if($this->_customUrl)
  		{
 -	 		if(!(is_array($getItems) || ($getItems instanceof Traversable)))
 -	 			$getItems=array();
 +			if(!(is_array($getItems) || ($getItems instanceof Traversable)))
 +				$getItems=array();
  			$key=$serviceID.':'.$serviceParam;
  			$wildCardKey = ($pos=strrpos($serviceParam,'.'))!==false ?  				$serviceID.':'.substr($serviceParam,0,$pos).'.*' : $serviceID.':*'; @@ -337,7 +356,7 @@ class TUrlMapping extends TUrlManager  					if($rule->supportCustomUrl($getItems))
  						return $rule->constructUrl($getItems,$encodeAmpersand,$encodeGetItems);
  				}
 -			}  +			}  			elseif(isset($this->_constructRules[$wildCardKey]))  			{  				foreach($this->_constructRules[$wildCardKey] as $rule)
 @@ -392,10 +411,12 @@ class TUrlMapping extends TUrlManager   * 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
 + * #^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.
 - * Notice that you need to escape the slash in regular expressions.
 + * 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,
 @@ -409,7 +430,7 @@ class TUrlMapping extends TUrlManager   * (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  + * ServiceParameters with a single rule. The pattern must contain the placeholder   * {*} for the ServiceParameter. For example   *   * <url ServiceParameter="adminpages.*" pattern="admin/{*}" /> @@ -417,24 +438,24 @@ class TUrlMapping extends TUrlManager   * 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:  + * 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  + * 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 fro wildcard patterns you can set  - * {@setUrlFormat UrlFormat} to 'Path':  + * To enable automatic parameter encoding in a path format fro 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  + * 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 @@ -518,8 +539,8 @@ class TUrlMappingPattern extends TComponent  	{
  		if($this->_serviceParameter===null)
  			throw new TConfigurationException('urlmappingpattern_serviceparameter_required', $this->getPattern());
 -		if(strpos($this->_serviceParameter,'*')!==false)  -		    $this->_isWildCardPattern=true; +		if(strpos($this->_serviceParameter,'*')!==false) +				$this->_isWildCardPattern=true;  	}
  	/**
 @@ -537,17 +558,17 @@ class TUrlMappingPattern extends TComponent  			$values[]='(?P<'.$key.'>'.$value.')';
  		}
  		if ($this->getIsWildCardPattern()) { -		    $params[]='{*}'; -		    // service parameter must not contain '=' and '/' -		    $values[]='(?P<'.$this->getServiceID().'>[^=/]+)'; +				$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';
 +				$regexp='/^'.$regexp.'$/u';
 +		else +				$regexp='/^'.$regexp.'(?P<urlparams>.*)$/u';
  		if(!$this->getCaseSensitive())
  			$regexp.='i';
 @@ -670,12 +691,12 @@ class TUrlMappingPattern extends TComponent  		if (isset($matches['urlparams']))  		{  			$params=explode('/',$matches['urlparams']); -			if ($this->_separator==='/')  +			if ($this->_separator==='/')  			{  				while($key=array_shift($params))  					$matches2[$key]=($value=array_shift($params)) ? $value : ''; -			}  -			else  +			} +			else  			{  				array_pop($params);  				foreach($params as $param)  | 
