| [ Index ] |
|
Code source de PRADO 3.0.6 |
1 <?php 2 /** 3 * TUrlMapping and TUrlMappingPattern class file. 4 * 5 * @author Wei Zhuo <weizhuo[at]gamil[dot]com> 6 * @link http://www.pradosoft.com/ 7 * @copyright Copyright © 2006 PradoSoft 8 * @license http://www.pradosoft.com/license/ 9 * @version $Id: TUrlMapping.php 1543 2006-12-03 13:00:54Z xue $ 10 * @package System.Web 11 */ 12 13 Prado::using('System.Web.TUrlManager'); 14 15 /** 16 * TUrlMapping Class 17 * 18 * The TUrlMapping module allows aributary URL path to be mapped to a 19 * particular service and page class. This module must be configured 20 * before a service is initialized, thus this module should be configured 21 * globally in the <tt>application.xml</tt> file and before any services. 22 * <code> 23 * <module id="friendly-url" class="System.Web.TUrlMapping"> 24 * <url ServiceParameter="Posts.ViewPost" pattern="post/{id}/?" parameters.id="\d+" /> 25 * <url ServiceParameter="Posts.ListPost" pattern="archive/{time}/?" parameters.time="\d{6}" /> 26 * <url ServiceParameter="Posts.ListPost" pattern="category/{cat}/?" parameters.cat="\d+" /> 27 * </module> 28 * <module id="request" class="THttpRequest" UrlManager="friendly-url" /> 29 * </code> 30 * 31 * See {@link TUrlMappingPattern} for details regarding the mapping patterns. 32 * Similar to other modules, the <tt><url /></tt> configuration class 33 * can be customised using the <tt>class</tt> property. 34 * 35 * The URL mapping are evaluated in order, only the first mapping that matches 36 * the URL will be used. Cascaded mapping can be achieved by placing the URL mappings 37 * in particular order. For example, placing the most specific mappings first. 38 * 39 * The mapping can be load from an external file by specifying a configuration 40 * file using the {@link setConfigFile ConfigFile} property. 41 * 42 * Since TUrlMapping is a URL manager extending from {@link TUrlManager}, 43 * you may override {@link TUrlManager::constructUrl} to support your pattern-based 44 * URL scheme. 45 * 46 * @author Wei Zhuo <weizhuo[at]gmail[dot]com> 47 * @version $Id: TUrlMapping.php 1543 2006-12-03 13:00:54Z xue $ 48 * @package System.Web 49 * @since 3.0.5 50 */ 51 class TUrlMapping extends TUrlManager 52 { 53 /** 54 * File extension of external configuration file 55 */ 56 const CONFIG_FILE_EXT='.xml'; 57 /** 58 * @var string default pattern class. 59 */ 60 private $_defaultPatternClass='TUrlMappingPattern'; 61 /** 62 * @var TUrlMappingPattern[] list of patterns. 63 */ 64 private $_patterns=array(); 65 /** 66 * @var TUrlMappingPattern matched pattern. 67 */ 68 private $_matched; 69 /** 70 * @var string external configuration file 71 */ 72 private $_configFile=null; 73 74 /** 75 * Initializes this module. 76 * This method is required by the IModule interface. 77 * @param TXmlElement configuration for this module, can be null 78 * @throws TConfigurationException if module is configured in the global scope. 79 */ 80 public function init($xml) 81 { 82 parent::init($xml); 83 if($this->getRequest()->getRequestResolved()) 84 throw new TConfigurationException('urlpath_dispatch_module_must_be_global'); 85 if($this->_configFile!==null) 86 $this->loadConfigFile(); 87 $this->loadUrlMappings($xml); 88 } 89 90 /** 91 * Initialize the module from configuration file. 92 * @throws TConfigurationException if {@link getConfigFile ConfigFile} is invalid. 93 */ 94 protected function loadConfigFile() 95 { 96 if(is_file($this->_configFile)) 97 { 98 $dom=new TXmlDocument; 99 $dom->loadFromFile($this->_configFile); 100 $this->loadUrlMappings($dom); 101 } 102 else 103 throw new TConfigurationException( 104 'urlpath_dispatch_configfile_invalid',$this->_configFile); 105 } 106 107 /** 108 * @return string external configuration file. Defaults to null. 109 */ 110 public function getConfigFile() 111 { 112 return $this->_configFile; 113 } 114 115 /** 116 * @param string external configuration file in namespace format. The file 117 * must be suffixed with '.xml'. 118 * @throws TInvalidDataValueException if the file is invalid. 119 */ 120 public function setConfigFile($value) 121 { 122 if(($this->_configFile=Prado::getPathOfNamespace($value,self::CONFIG_FILE_EXT))===null) 123 throw new TConfigurationException('logrouter_configfile_invalid',$value); 124 } 125 126 /** 127 * Load and configure each url mapping pattern. 128 * @param TXmlElement configuration node 129 * @throws TConfigurationException if specific pattern class is invalid 130 */ 131 protected function loadUrlMappings($xml) 132 { 133 foreach($xml->getElementsByTagName('url') as $url) 134 { 135 $properties=$url->getAttributes(); 136 $class=$properties->remove('class'); 137 if($class===null) 138 $class = $this->_defaultPatternClass; 139 $pattern = Prado::createComponent($class); 140 if(!($pattern instanceof TUrlMappingPattern)) 141 throw new TConfigurationException('urlpath_dispatch_invalid_pattern_class'); 142 foreach($properties as $name=>$value) 143 $pattern->setSubproperty($name,$value); 144 $this->_patterns[] = $pattern; 145 $pattern->init($url); 146 } 147 } 148 149 /** 150 * Parses the request URL and returns an array of input parameters. 151 * This method overrides the parent implementation. 152 * The input parameters do not include GET and POST variables. 153 * This method uses the request URL path to find the first matching pattern. If found 154 * the matched pattern parameters are used to return as the input parameters. 155 * @return array list of input parameters 156 */ 157 public function parseUrl() 158 { 159 $url = $this->getRequest()->getUrl(); 160 foreach($this->_patterns as $pattern) 161 { 162 $matches = $pattern->getPatternMatches($url); 163 if(count($matches) > 0) 164 { 165 $this->_matched=$pattern; 166 $this->changeServiceParameters($pattern); 167 $params=array(); 168 foreach($matches as $key=>$value) 169 if(is_string($key)) 170 $params[$key]=$value; 171 return $params; 172 } 173 } 174 return parent::parseUrl(); 175 } 176 177 /** 178 * @return TUrlMappingPattern the matched pattern, null if not found. 179 */ 180 public function getMatchingPattern() 181 { 182 return $this->_matched; 183 } 184 185 /** 186 * @param TUrlMappingPattern change the Request service ID and page class. 187 */ 188 protected function changeServiceParameters($pattern) 189 { 190 $request = $this->getRequest(); 191 $id = $pattern->getServiceID(); 192 $param = $pattern->getServiceParameter(); 193 $request->setServiceID($id); 194 $request->setServiceParameter($param); 195 $request->add($id,$param); 196 } 197 } 198 199 /** 200 * URL Mapping Pattern Class 201 * 202 * Describes an URL mapping pattern, if a given URL matches the pattern, the 203 * TUrlMapping class will alter the THttpRequest parameters. The 204 * url matching is done using patterns and regular expressions. 205 * 206 * The {@link setPattern Pattern} property takes an string expression with 207 * parameter names enclosed between a left brace '{' and a right brace '}'. 208 * The pattens for each parameter can be set using {@link getParameters Parameters} 209 * attribute collection. For example 210 * <code> 211 * <url ... pattern="articles/{year}/{month}/{day}" 212 * parameters.year="\d{4}" parameters.month="\d{2}" parameters.day="\d+" /> 213 * </code> 214 * 215 * In the above example, the pattern contains 3 parameters named "year", 216 * "month" and "day". The pattern for these parameters are, respectively, 217 * "\d{4}" (4 digits), "\d{2}" (2 digits) and "\d+" (1 or more digits). 218 * Essentially, the <tt>Parameters</tt> attribute name and values are used 219 * as substrings in replacing the placeholders in the <tt>Pattern</tt> string 220 * to form a complete regular expression string. A full regular expression 221 * may be expressed using the <tt>RegularExpression</tt> attribute or 222 * as the body content of the <module> tag. The above pattern is equivalent 223 * to the following regular expression pattern. 224 * <code> 225 * /articles\/(?P<year>\d{4})\/(?P<month>\d{2})\/(?P<day>\d+)/u 226 * </code> 227 * The above regular expression used the "named group" feature available in PHP. 228 * Notice that you need to escape the slash in regular expressions. 229 * 230 * In the TUrlMappingPattern class, the pattern is matched against the 231 * <b>path</b> property of the url only. 232 * 233 * Thus, only an url that matches the pattern will be valid. For example, 234 * an url "<tt>http://example.com/articles/2006/07/21</tt>" will matches and is valid. 235 * However, "<tt>http://example.com/articles/2006/07/hello</tt>" is not 236 * valid since the "day" parameter pattern is not satisfied. 237 * 238 * The parameter values are available through the standard <tt>Request</tt> 239 * object. For example, <tt>$this->Request['year']</tt>. 240 * 241 * The {@link setServiceParameter ServiceParameter} and {@link setServiceID ServiceID} 242 * (the default ID is 'page') set the service parameter and service id respectively. 243 * The service parameter for the TPageService is the Page class name, other service 244 * may use the service parameter differently. 245 * 246 * For more complicated mappings, the body of the <tt><url></tt> 247 * can be used to specify the mapping pattern. 248 * 249 * @author Wei Zhuo <weizhuo[at]gmail[dot]com> 250 * @version $Id: TUrlMapping.php 1543 2006-12-03 13:00:54Z xue $ 251 * @package System.Web 252 * @since 3.0.5 253 */ 254 class TUrlMappingPattern extends TComponent 255 { 256 /** 257 * @var string service parameter such as Page class name. 258 */ 259 private $_serviceParameter; 260 /** 261 * @var string service ID, default is 'page'. 262 */ 263 private $_serviceID='page'; 264 /** 265 * @var string url pattern to match. 266 */ 267 private $_pattern; 268 /** 269 * @var TMap parameter regular expressions. 270 */ 271 private $_parameters; 272 /** 273 * @var string regular expression pattern. 274 */ 275 private $_regexp; 276 /** 277 * @var boolean case sensitive matching, default is true 278 */ 279 private $_caseSensitive=true; 280 281 public function __construct() 282 { 283 $this->_parameters = Prado::createComponent('System.Collections.TAttributeCollection'); 284 } 285 286 /** 287 * Initialize the pattern, uses the body content as pattern is available. 288 * @param TXmlElement configuration for this module. 289 * @throws TConfigurationException if page class is not specified. 290 */ 291 public function init($config) 292 { 293 $body = trim($config->getValue()); 294 if(strlen($body)>0) 295 $this->setRegularExpression($body); 296 if(is_null($this->_serviceParameter)) 297 { 298 throw new TConfigurationException( 299 'dispatcher_url_service_parameter_missing', $this->getPattern()); 300 } 301 } 302 303 /** 304 * Subsitutue the parameter key value pairs as named groupings 305 * in the regular expression matching pattern. 306 * @return string regular expression pattern with parameter subsitution 307 */ 308 protected function getParameterizedPattern() 309 { 310 $params= array(); 311 $values = array(); 312 foreach($this->parameters as $key => $value) 313 { 314 $params[] = '{'.$key.'}'; 315 $values[] = '(?P<'.$key.'>'.$value.')'; 316 } 317 $params[] = '/'; 318 $values[] = '\\/'; 319 $regexp = str_replace($params,$values,$this->getPattern()); 320 $modifiers = $this->getModifiers(); 321 return '/'.$regexp.'/'.$modifiers; 322 } 323 324 /** 325 * @return string full regular expression mapping pattern 326 */ 327 public function getRegularExpression() 328 { 329 return $this->_regexp; 330 } 331 332 /** 333 * @param string full regular expression mapping patern. 334 */ 335 public function setRegularExpression($value) 336 { 337 $this->_regexp=$value; 338 } 339 340 /** 341 * @param string service parameter, such as page class name. 342 */ 343 public function setServiceParameter($value) 344 { 345 $this->_serviceParameter=$value; 346 } 347 348 /** 349 * @return string service parameter, such as page class name. 350 */ 351 public function getServiceParameter() 352 { 353 return $this->_serviceParameter; 354 } 355 356 /** 357 * @param string service id to handle. 358 */ 359 public function setServiceID($value) 360 { 361 $this->_serviceID=$value; 362 } 363 364 /** 365 * @return string service id. 366 */ 367 public function getServiceID() 368 { 369 return $this->_serviceID; 370 } 371 372 /** 373 * @return string url pattern to match. 374 */ 375 public function getPattern() 376 { 377 return $this->_pattern; 378 } 379 380 /** 381 * @param string url pattern to match. 382 */ 383 public function setPattern($value) 384 { 385 $this->_pattern = $value; 386 } 387 388 /** 389 * @param boolean case sensitive pattern matching, default is true. 390 */ 391 public function setCaseSensitive($value) 392 { 393 $this->_caseSensitive=TPropertyValue::ensureBoolean($value); 394 } 395 396 /** 397 * @return boolean case sensitive pattern matching, default is true. 398 */ 399 public function getCaseSensitive() 400 { 401 return $this->_caseSensitive; 402 } 403 404 /** 405 * @return TAttributeCollection parameter key value pairs. 406 */ 407 public function getParameters() 408 { 409 return $this->_parameters; 410 } 411 412 /** 413 * @param TAttributeCollection new parameter key value pairs. 414 */ 415 public function setParameters($value) 416 { 417 $this->_parameters=$value; 418 } 419 420 /** 421 * Uses URL pattern (or full regular expression if available) to 422 * match the given url path. 423 * @param TUri url to match against 424 * @return array matched parameters, empty if no matches. 425 */ 426 public function getPatternMatches($url) 427 { 428 $path = $url->getPath(); 429 $matches=array(); 430 $pattern = $this->getRegularExpression(); 431 if($pattern === null) 432 $pattern = $this->getParameterizedPattern(); 433 preg_match($pattern, $path, $matches); 434 return $matches; 435 } 436 437 /** 438 * @return string regular expression matching modifiers. 439 */ 440 protected function getModifiers() 441 { 442 $modifiers = 'u'; 443 if(!$this->getCaseSensitive()) 444 $modifiers .= 'i'; 445 return $modifiers; 446 } 447 } 448 449 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
| Généré le : Sun Feb 25 21:07:04 2007 | par Balluche grâce à PHPXref 0.7 |