summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--HISTORY2
-rw-r--r--demos/quickstart/protected/pages/Configurations/UrlMapping.page71
-rw-r--r--framework/Web/TUrlMapping.php71
3 files changed, 89 insertions, 55 deletions
diff --git a/HISTORY b/HISTORY
index d0be41db..c01010c0 100644
--- a/HISTORY
+++ b/HISTORY
@@ -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&amp;id=123</tt></li>
- <li><tt>/index.php/archive/200605</tt> is recognized as <tt>/index.php?page=Posts.ListPost&amp;time=200605</tt></li>
- <li><tt>/index.php/category/2</tt> is recognized as <tt>/index.php?page=Posts.ListPost&amp;cat=2</tt></li>
+ <li><tt>/index.php/post/123</tt> is recognized as <tt>/index.php?page=Posts.ViewPost&amp;id=123</tt></li>
+ <li><tt>/index.php/archive/200605</tt> is recognized as <tt>/index.php?page=Posts.ListPost&amp;time=200605</tt></li>
+ <li><tt>/index.php/category/2</tt> is recognized as <tt>/index.php?page=Posts.ListPost&amp;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&amp;id=123</tt></li>
- <li><tt>/index.php/post/ListPost/123</tt> is recognized as <tt>/index.php?page=Posts.ListPost&amp;id=123</tt></li>
- <li><tt>/index.php/post/ListPost/123</tt> is recognized as <tt>/index.php?page=Posts.ListPost&amp;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&amp;id=123</tt></li>
+ <li><tt>/index.php/post/ListPost/123</tt> is recognized as <tt>/index.php?page=Posts.ListPost&amp;id=123</tt></li>
+ <li><tt>/index.php/post/ListPost/123</tt> is recognized as <tt>/index.php?page=Posts.ListPost&amp;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&amp;cat=15&amp;month=12</tt></li>
- <li><tt>/index.php/edit/id/12</tt> is recognized as <tt>/index.php?page=list&amp;id=12</tt></li>
- <li><tt>/index.php/show/name/foo</tt> is recognized as <tt>/index.php?page=show&amp;name=foo</tt></li>
- <li><tt>/index.php/admin/edit/id/12</tt> is recognized as <tt>/index.php?page=user.admin.edit&amp;id=12</tt></li>
+ <li><tt>/index.php/list/cat/15/month/12</tt> is recognized as <tt>/index.php?page=list&amp;cat=15&amp;month=12</tt></li>
+ <li><tt>/index.php/edit/id/12</tt> is recognized as <tt>/index.php?page=list&amp;id=12</tt></li>
+ <li><tt>/index.php/show/name/foo</tt> is recognized as <tt>/index.php?page=show&amp;name=foo</tt></li>
+ <li><tt>/index.php/admin/edit/id/12</tt> is recognized as <tt>/index.php?page=user.admin.edit&amp;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)