Changeset 2101
- Timestamp:
- 08/02/2007 08:49:49 AM
- Files:
-
- trunk/HISTORY (modified) (1 diff)
- trunk/framework/Exceptions/messages.txt (modified) (1 diff)
- trunk/framework/Web/TUrlMapping.php (modified) (18 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/HISTORY
r2100 r2101 11 11 ENH: Ticket#667 - Added TFeedService.ContentType property (Qiang) 12 12 ENH: Ticket#678 - Improved DateTimeFormatInfo performance (Stever) 13 ENH: Ticket#681 - TUrlMapping can construct custom URLs now (Qiang) 13 14 ENH: Added THead requirement check (Qiang) 14 15 CHG: GeSHi is replaced with Text_Highlighter (Christophe) trunk/framework/Exceptions/messages.txt
r2096 r2101 419 419 cachesession_cachemodule_inexistent = TCacheHttpSession.CacheModuleID '{0}' points to a non-existent module. 420 420 cachesession_cachemodule_invalid = TCacheHttpSession.CacheModuleID '{0}' points to a module that does not implement ICache interface. 421 422 urlmapping_urlmappingpattern_required = TUrlMapping can only contain TUrlMappingPattern or its child classes. 423 urlmappingpattern_serviceparameter_required = TUrlMappingPattern.ServiceParameter is required for pattern '{0}'. trunk/framework/Web/TUrlMapping.php
r2020 r2101 12 12 13 13 Prado::using('System.Web.TUrlManager'); 14 Prado::using('System.Collections.TAttributeCollection'); 14 15 15 16 /** … … 21 22 * globally in the <tt>application.xml</tt> file and before any services. 22 23 * <code> 24 * <module id="request" class="THttpRequest" UrlManager="friendly-url" /> 23 25 * <module id="friendly-url" class="System.Web.TUrlMapping"> 24 26 * <url ServiceParameter="Posts.ViewPost" pattern="post/{id}/?" parameters.id="\d+" /> … … 26 28 * <url ServiceParameter="Posts.ListPost" pattern="category/{cat}/?" parameters.cat="\d+" /> 27 29 * </module> 28 * <module id="request" class="THttpRequest" UrlManager="friendly-url" />29 30 * </code> 30 31 * … … 37 38 * in particular order. For example, placing the most specific mappings first. 38 39 * 39 * The mapping can be load from an external file by specifying a configuration40 * The mapping can be loaded from an external file by specifying a configuration 40 41 * file using the {@link setConfigFile ConfigFile} property. 41 42 * … … 43 44 * you may override {@link TUrlManager::constructUrl} to support your pattern-based 44 45 * URL scheme. 46 * 47 * From PRADO v3.1.1, TUrlMapping also provides support to construct URLs according to 48 * the specified the pattern. You may enable this functionality by setting {@link setEnableCustomUrl EnableCustomUrl} to true. 49 * When you call THttpRequest::constructUrl() (or via TPageService::constructUrl()), 50 * TUrlMapping will examine the available URL mapping patterns using their {@link getServiceParameter ServiceParameter} 51 * and {@link getPattern Pattern} properties. A pattern is applied if its 52 * {@link getServiceParameter ServiceParameter} matches the service parameter passed 53 * to constructUrl() and every parameter in the {@link getPattern Pattern} is found 54 * in the GET variables. 45 55 * 46 56 * @author Wei Zhuo <weizhuo[at]gmail[dot]com> … … 56 66 const CONFIG_FILE_EXT='.xml'; 57 67 /** 58 * @var string default pattern class.59 */60 private $_defaultPatternClass='TUrlMappingPattern';61 /**62 68 * @var TUrlMappingPattern[] list of patterns. 63 69 */ … … 71 77 */ 72 78 private $_configFile=null; 79 /** 80 * @var boolean whether to enable custom contructUrl 81 */ 82 private $_customUrl=false; 83 /** 84 * @var array rules for constructing URLs 85 */ 86 private $_constructRules=array(); 87 88 private $_urlPrefix=''; 73 89 74 90 /** … … 86 102 $this->loadConfigFile(); 87 103 $this->loadUrlMappings($xml); 104 if($this->_urlPrefix==='') 105 $this->_urlPrefix=$this->getRequest()->getApplicationUrl(); 106 $this->_urlPrefix=rtrim($this->_urlPrefix,'/'); 88 107 } 89 108 … … 106 125 107 126 /** 127 * Returns a value indicating whether to enable custom constructUrl. 128 * If true, constructUrl() will make use of the URL mapping rules to 129 * construct valid URLs. 130 * @return boolean whether to enable custom constructUrl. Defaults to false. 131 */ 132 public function getEnableCustomUrl() 133 { 134 return $this->_customUrl; 135 } 136 137 /** 138 * Sets a value indicating whether to enable custom constructUrl. 139 * If true, constructUrl() will make use of the URL mapping rules to 140 * construct valid URLs. 141 * @param boolean whether to enable custom constructUrl. 142 */ 143 public function setEnableCustomUrl($value) 144 { 145 $this->_customUrl=TPropertyValue::ensureBoolean($value); 146 } 147 148 /** 149 * @return string the part that will be prefixed to the constructed URLs. Defaults to the requested script path (e.g. /path/to/index.php for a URL http://hostname/path/to/index.php) 150 */ 151 public function getUrlPrefix() 152 { 153 return $this->_urlPrefix; 154 } 155 156 /** 157 * @param string the part that will be prefixed to the constructed URLs. This is used by constructUrl() when EnableCustomUrl is set true. 158 * @see getUrlPrefix 159 */ 160 public function setUrlPrefix($value) 161 { 162 $this->_urlPrefix=$value; 163 } 164 165 /** 108 166 * @return string external configuration file. Defaults to null. 109 167 */ … … 134 192 { 135 193 $properties=$url->getAttributes(); 136 $class=$properties->remove('class'); 137 if($class===null) 138 $class = $this->_defaultPatternClass; 139 $pattern = Prado::createComponent($class); 194 if(($class=$properties->remove('class'))===null) 195 $class='TUrlMappingPattern'; 196 $pattern = Prado::createComponent($class,$this); 140 197 if(!($pattern instanceof TUrlMappingPattern)) 141 throw new TConfigurationException('url path_dispatch_invalid_pattern_class');198 throw new TConfigurationException('urlmapping_urlmappingpattern_required'); 142 199 foreach($properties as $name=>$value) 143 200 $pattern->setSubproperty($name,$value); 144 201 $this->_patterns[] = $pattern; 145 202 $pattern->init($url); 203 204 $key=$pattern->getServiceID().':'.$pattern->getServiceParameter(); 205 $this->_constructRules[$key][]=$pattern; 146 206 } 147 207 } … … 176 236 177 237 /** 238 * Constructs a URL that can be recognized by PRADO. 239 * 240 * This method provides the actual implementation used by {@link THttpRequest::constructUrl}. 241 * Override this method if you want to provide your own way of URL formatting. 242 * If you do so, you may also need to override {@link parseUrl} so that the URL can be properly parsed. 243 * 244 * The URL is constructed as the following format: 245 * /entryscript.php?serviceID=serviceParameter&get1=value1&... 246 * If {@link THttpRequest::setUrlFormat THttpRequest.UrlFormat} is 'Path', 247 * the following format is used instead: 248 * /entryscript.php/serviceID/serviceParameter/get1,value1/get2,value2... 249 * @param string service ID 250 * @param string service parameter 251 * @param array GET parameters, null if not provided 252 * @param boolean whether to encode the ampersand in URL 253 * @param boolean whether to encode the GET parameters (their names and values) 254 * @return string URL 255 * @see parseUrl 256 * @since 3.1.1 257 */ 258 public function constructUrl($serviceID,$serviceParam,$getItems,$encodeAmpersand,$encodeGetItems) 259 { 260 if(!$this->_customUrl || !(is_array($getItems) || ($getItems instanceof Traversable))) 261 return parent::constructUrl($serviceID,$serviceParam,$getItems,$encodeAmpersand,$encodeGetItems); 262 263 $key=$serviceID.':'.$serviceParam; 264 if(isset($this->_constructRules[$key])) 265 { 266 foreach($this->_constructRules[$key] as $rule) 267 { 268 if($rule->supportCustomUrl($getItems)) 269 return $rule->constructUrl($getItems,$encodeAmpersand,$encodeGetItems); 270 } 271 } 272 return parent::constructUrl($serviceID,$serviceParam,$getItems,$encodeAmpersand,$encodeGetItems); 273 } 274 275 /** 178 276 * @return TUrlMappingPattern the matched pattern, null if not found. 179 277 */ … … 252 350 * @var string url pattern to match. 253 351 */ 254 private $_pattern ;352 private $_pattern=''; 255 353 /** 256 354 * @var TMap parameter regular expressions. … … 260 358 * @var string regular expression pattern. 261 359 */ 262 private $_regexp ;360 private $_regexp=''; 263 361 /** 264 362 * @var boolean case sensitive matching, default is true … … 266 364 private $_caseSensitive=true; 267 365 268 public function __construct() 269 { 270 $this->_parameters = Prado::createComponent('System.Collections.TAttributeCollection'); 366 private $_customUrl=true; 367 368 private $_manager; 369 370 public function __construct(TUrlManager $manager) 371 { 372 $this->_manager=$manager; 373 $this->_parameters=new TAttributeCollection; 374 $this->_parameters->setCaseSensitive(true); 375 } 376 377 public function getManager() 378 { 379 return $this->_manager; 271 380 } 272 381 … … 278 387 public function init($config) 279 388 { 280 $body = trim($config->getValue()); 281 if(strlen($body)>0) 389 if(($body=trim($config->getValue()))!=='') 282 390 $this->setRegularExpression($body); 283 if(is_null($this->_serviceParameter)) 284 { 285 throw new TConfigurationException( 286 'dispatcher_url_service_parameter_missing', $this->getPattern()); 287 } 391 if($this->_serviceParameter===null) 392 throw new TConfigurationException('urlmappingpattern_serviceparameter_required', $this->getPattern()); 288 393 } 289 394 … … 358 463 359 464 /** 360 * @return string url pattern to match. 465 * @return string url pattern to match. Defaults to ''. 361 466 */ 362 467 public function getPattern() … … 413 518 public function getPatternMatches($url) 414 519 { 415 $path = $url->getPath();416 520 $matches=array(); 417 $pattern = $this->getRegularExpression(); 418 if($pattern === null) 419 $pattern = $this->getParameterizedPattern(); 420 preg_match($pattern, $path, $matches); 521 if(($pattern=$this->getRegularExpression())==='') 522 $pattern=$this->getParameterizedPattern(); 523 preg_match($pattern,$url->getPath(),$matches); 421 524 return $matches; 422 525 } … … 432 535 return $modifiers; 433 536 } 537 538 /** 539 * Returns a value indicating whether to use this pattern to construct URL. 540 * @return boolean whether to enable custom constructUrl. Defaults to true. 541 * @since 3.1.1 542 */ 543 public function getEnableCustomUrl() 544 { 545 return $this->_customUrl; 546 } 547 548 /** 549 * Sets a value indicating whether to enable custom constructUrl using this pattern 550 * @param boolean whether to enable custom constructUrl. 551 */ 552 public function setEnableCustomUrl($value) 553 { 554 $this->_customUrl=TPropertyValue::ensureBoolean($value); 555 } 556 557 /** 558 * @param array list of GET items to be put in the constructed URL 559 * @return boolean whether this pattern IS the one for constructing the URL with the specified GET items. 560 * @since 3.1.1 561 */ 562 public function supportCustomUrl($getItems) 563 { 564 if(!$this->_customUrl || $this->getPattern()==='') 565 return false; 566 foreach($this->_parameters as $key=>$value) 567 if(!isset($getItems[$key])) 568 return false; 569 570 return true; 571 } 572 573 /** 574 * Constructs a URL using this pattern. 575 * @param array list of GET variables 576 * @param boolean whether the ampersand should be encoded in the constructed URL 577 * @param boolean whether the GET variables should be encoded in the constructed URL 578 * @return string the constructed URL 579 * @since 3.1.1 580 */ 581 public function constructUrl($getItems,$encodeAmpersand,$encodeGetItems) 582 { 583 $extra=array(); 584 $replace=array(); 585 // for the GET variables matching the pattern, put them in the URL path 586 foreach($getItems as $key=>$value) 587 { 588 if($encodeGetItems) 589 $value=urlencode($value); 590 if($this->_parameters->contains($key)) 591 $replace['{'.$key.'}']=$value; 592 else 593 $extra[$key]=$value; 594 } 595 596 $url=$this->_manager->getUrlPrefix().'/'.trim(strtr($this->getPattern(),$replace),'/'); 597 598 // for the rest of the GET variables, put them in the query string 599 if(count($extra)>0) 600 { 601 $url2=''; 602 $amp=$encodeAmpersand?'&':'&'; 603 if($encodeGetItems) 604 { 605 foreach($extra as $name=>$value) 606 { 607 if(is_array($value)) 608 { 609 $name=urlencode($name.'[]'); 610 foreach($value as $v) 611 $url2.=$amp.$name.'='.urlencode($v); 612 } 613 else 614 $url2.=$amp.urlencode($name).'='.urlencode($value); 615 } 616 } 617 else 618 { 619 foreach($extra as $name=>$value) 620 { 621 if(is_array($value)) 622 { 623 foreach($value as $v) 624 $url2.=$amp.$name.'[]='.$v; 625 } 626 else 627 $url2.=$amp.$name.'='.$value; 628 } 629 } 630 $url=$url.'?'.substr($url2,strlen($amp)); 631 } 632 return $url; 633 } 434 634 } 435 635
