Changeset 1539

Show
Ignore:
Timestamp:
12/02/2006 01:20:40 PM (2 years ago)
Author:
xue
Message:

added TUrlManager and fixed #451.

Location:
branches/3.0
Files:
1 added
5 modified

Legend:

Unmodified
Added
Removed
  • branches/3.0/HISTORY

    r1536 r1539  
    88BUG: TPager would not display if it was invisible previously (Qiang) 
    99ENH: Ticket#446 - Added TMetaTagCollection.getMetaTagByID method (Qiang) 
     10ENH: Ticket#451 - Modified TUrlMapping to extend from TUrlManager (Qiang) 
    1011ENH: Ticket#468 - Added support of using all property tags in skins (Qiang) 
    1112ENH: Ticket#471 - Added methods in TAssetManager to expose published path and URL (Qiang) 
     
    1718CHG: THttpRequest.constructUrl() now encodes ampersand by default (Qiang) 
    1819CHG: TDataBoundControl will not throw exception if CurrentPageIndex is out of range (Qiang) 
     20NEW: TUrlManager (Qiang) 
    1921 
    2022Version 3.0.5 October 23, 2006 
  • branches/3.0/framework/Exceptions/messages.txt

    r1536 r1539  
    4848 
    4949uri_format_invalid                                              = '{0}' is not a valid URI. 
     50 
     51httprequest_separator_invalid                   = THttpRequest.UrlParamSeparator can only contain a single character. 
     52httprequest_urlmanager_inexist                  = THttpRequest.UrlManager '{0}' does not point to an existing module. 
     53httprequest_urlmanager_invalid                  = THttpRequest.UrlManager '{0}' must point to a module extending from TUrlManager. 
    5054 
    5155httpresponse_bufferoutput_unchangeable  = THttpResponse.BufferOutput cannot be modified after THttpResponse is initialized. 
  • branches/3.0/framework/TApplication.php

    r1512 r1539  
    880880                $request->setAvailableServices($serviceIDs); 
    881881 
     882                $request->resolveRequest(); 
     883 
    882884                if(($serviceID=$request->getServiceID())===null) 
    883885                        $serviceID=self::PAGE_SERVICE_ID; 
  • branches/3.0/framework/Web/THttpRequest.php

    r1508 r1539  
    1010 * @package System.Web 
    1111 */ 
     12 
     13Prado::using('System.Web.TUrlManager'); 
    1214 
    1315/** 
     
    3941 * 
    4042 * To construct a URL that can be recognized by Prado, use {@link constructUrl()}. 
     43 * The format of the recognizable URLs is determined according to 
     44 * {@link setUrlManager UrlManager}. By default, the following two formats 
     45 * are recognized: 
     46 * <code> 
     47 * /index.php?ServiceID=ServiceParameter&Name1=Value1&Name2=Value2 
     48 * /index.php/ServiceID,ServiceParameter/Name1,Value1/Name2,Value2 
     49 * </code> 
     50 * The first format is called 'Get' while the second 'Path', which is specified 
     51 * via {@link setUrlFormat UrlFormat}. For advanced users who want to use 
     52 * their own URL formats, they can write customized URL management modules 
     53 * and install the managers as application modules and set {@link setUrlManager UrlManager}. 
     54 * 
     55 * The ServiceID in the above URLs is as defined in the application configuration 
     56 * (e.g. the default page service's service ID is 'page'). 
     57 * As a consequence, your GET variable names should not conflict with the service 
     58 * IDs that your application supports. 
     59 * 
    4160 * THttpRequest also provides the cookies sent by the user, user information such 
    4261 * as his browser capabilities, accepted languages, etc. 
    43  * Currently, THttpRequest recognizes the following URL format: 
    44  * <code> 
    45  * /index.php?ServiceID=ServiceParameter 
    46  * </code> 
    47  * where ServiceID is as defined in the application configuration (e.g. 
    48  * the default page service's service ID is 'page'). 
    49  * Therefore, your GET variable names should not conflict with the service 
    50  * IDs that your application supports. 
    5162 * 
    5263 * By default, THttpRequest is registered with {@link TApplication} as the 
     
    6172{ 
    6273        /** 
    63          * Separator used to separate GET variable name and value when URL format is Path. 
     74         * @var TUrlManager the URL manager module 
     75         */ 
     76        private $_urlManager=null; 
     77        /** 
     78         * @var string the ID of the URL manager module 
     79         */ 
     80        private $_urlManagerID=''; 
     81        /** 
     82         * @var string Separator used to separate GET variable name and value when URL format is Path. 
    6483         */ 
    6584        private $_separator=','; 
    6685        /** 
    67          * @var boolean whether the module is initialized 
    68          */ 
    69         private $_initialized=false; 
    70         /** 
    7186         * @var string requested service ID 
    7287         */ 
     
    88103         */ 
    89104        private $_pathInfo; 
    90  
     105        /** 
     106         * @var boolean whether the session ID should be kept in cookie only 
     107         */ 
     108        private $_cookieOnly=false; 
    91109        private $_urlFormat=THttpRequestUrlFormat::Get; 
    92110        private $_services; 
     
    131149        public function init($config) 
    132150        { 
     151                if(empty($this->_urlManagerID)) 
     152                { 
     153                        $this->_urlManager=new TUrlManager; 
     154                        $this->_urlManager->init(null); 
     155                } 
     156                else 
     157                { 
     158                        $this->_urlManager=$this->getApplication()->getModule($this->_urlManagerID); 
     159                        if($this->_urlManager===null) 
     160                                throw new TConfigurationException('httprequest_urlmanager_inexist',$this->_urlManagerID); 
     161                        if(!($this->_urlManager instanceof TUrlManager)) 
     162                                throw new TConfigurationException('httprequest_urlmanager_invalid',$this->_urlManagerID); 
     163                } 
     164 
    133165                // Fill in default request info when the script is run in command line 
    134166                if(php_sapi_name()==='cli') 
     
    140172                        $_SERVER['HTTP_USER_AGENT']=''; 
    141173                } 
     174 
     175                $this->_cookieOnly=(int)ini_get('session.use_cookies') && (int)ini_get('session.use_only_cookies'); 
    142176 
    143177                // Info about server variables: 
     
    171205                } 
    172206 
    173                 if($this->getUrlFormat()===THttpRequestUrlFormat::Path && ($pathInfo=trim($this->_pathInfo,'/'))!=='') 
    174                         $this->_items=array_merge($this->parseUrl(),$_POST); 
    175                 else 
    176                         $this->_items=array_merge($_GET,$_POST); 
    177  
    178                 $this->_initialized=true; 
    179207                $this->getApplication()->setRequest($this); 
    180208        } 
     
    213241                } 
    214242                return $this->_url; 
     243        } 
     244 
     245        /** 
     246         * @return string the ID of the URL manager module 
     247         */ 
     248        public function getUrlManager() 
     249        { 
     250                return $this->_urlManagerID; 
     251        } 
     252 
     253        /** 
     254         * Sets the URL manager module. 
     255         * By default, {@link TUrlManager} is used for managing URLs. 
     256         * You may specify a different module for URL managing tasks 
     257         * by loading it as an application module and setting this property 
     258         * with the module ID. 
     259         * @param string the ID of the URL manager module 
     260         */ 
     261        public function setUrlManager($value) 
     262        { 
     263                $this->_urlManagerID=$value; 
     264        } 
     265 
     266        /** 
     267         * @return TUrlManager the URL manager module 
     268         */ 
     269        public function getUrlManagerModule() 
     270        { 
     271                return $this->_urlManager; 
    215272        } 
    216273 
     
    473530 
    474531        /** 
    475          * Constructs a URL that is recognizable by Prado. 
    476          * You may override this method to provide your own way of URL formatting. 
    477          * If you do so, you may also need to override {@link parseUrl} so that the URL can be properly parsed. 
    478          * The URL is constructed as the following format: 
    479          * /entryscript.php?serviceID=serviceParameter&get1=value1&... 
    480          * If {@link setUrlFormat UrlFormat} is Path, the following format is used instead: 
    481          * /entryscript.php/serviceID/serviceParameter/get1,value1/get2,value2... 
     532         * Constructs a URL that can be recognized by PRADO. 
     533         * The actual construction work is done by the URL manager module. 
     534         * This method may append session information to the generated URL if needed. 
     535         * You may provide your own URL manager module by setting {@link setUrlManager UrlManager} 
     536         * to provide your own URL scheme. 
    482537         * @param string service ID 
    483538         * @param string service parameter 
     
    486541         * @param boolean whether to encode the GET parameters (their names and values), defaults to false. 
    487542         * @return string URL 
    488          * @see parseUrl 
     543         * @see TUrlManager::constructUrl 
    489544         */ 
    490545        public function constructUrl($serviceID,$serviceParam,$getItems=null,$encodeAmpersand=true,$encodeGetItems=true) 
    491546        { 
    492                 $url=$serviceID.'='.$serviceParam; 
    493                 $amp=$encodeAmpersand?'&amp;':'&'; 
    494                 if(is_array($getItems) || $getItems instanceof Traversable) 
    495                 { 
    496                         if($encodeGetItems) 
    497                         { 
    498                                 foreach($getItems as $name=>$value) 
    499                                 { 
    500                                         if(is_array($value)) 
    501                                         { 
    502                                                 $name=urlencode($name.'[]'); 
    503                                                 foreach($value as $v) 
    504                                                         $url.=$amp.$name.'='.urlencode($v); 
    505                                         } 
    506                                         else 
    507                                                 $url.=$amp.urlencode($name).'='.urlencode($value); 
    508                                 } 
    509                         } 
    510                         else 
    511                         { 
    512                                 foreach($getItems as $name=>$value) 
    513                                 { 
    514                                         if(is_array($value)) 
    515                                         { 
    516                                                 foreach($value as $v) 
    517                                                         $url.=$amp.$name.'[]='.$v; 
    518                                         } 
    519                                         else 
    520                                                 $url.=$amp.$name.'='.$value; 
    521                                 } 
    522                         } 
    523                 } 
    524                 if($this->getUrlFormat()===THttpRequestUrlFormat::Path) 
    525                 { 
    526                         $url=strtr($url,array($amp=>'/','?'=>'/','='=>$this->_separator)); 
    527                         if(defined('SID') && SID != '' && !((int)ini_get('session.use_cookies')===1 && ((int)ini_get('session.use_only_cookies')===1))) 
    528                                 $url.='?'.SID; 
    529                         return $this->getApplicationUrl().'/'.$url; 
    530                 } 
     547                $url=$this->_urlManager->constructUrl($serviceID,$serviceParam,$getItems,$encodeAmpersand,$encodeGetItems); 
     548                if(defined('SID') && SID != '' && !$this->_cookieOnly) 
     549                        return $url . (strpos($url,'?')===false? '?' : ($encodeAmpersand?'&amp;':'&')) . SID; 
    531550                else 
    532                 { 
    533                         if(defined('SID') && SID != '' && !((int)ini_get('session.use_cookies')===1 && ((int)ini_get('session.use_only_cookies')===1))) 
    534                                 $url.=$amp.SID; 
    535                         return $this->getApplicationUrl().'?'.$url; 
    536                 } 
    537         } 
    538  
    539         /** 
    540          * Parses the request URL and returns an array of input parameters (including GET variables). 
    541          * This method is invoked when the URL format is Path. 
     551                        return $url; 
     552        } 
     553 
     554        /** 
     555         * Parses the request URL and returns an array of input parameters (excluding GET variables). 
    542556         * You may override this method to support customized URL format. 
    543557         * @return array list of input parameters, indexed by parameter names 
    544          * @see constructUrl 
     558         * @see TUrlManager::parseUrl 
    545559         */ 
    546560        protected function parseUrl() 
    547561        { 
    548                 if($this->_pathInfo!=='') 
    549                 { 
    550                         $paths=explode('/',$this->_pathInfo); 
    551                         $getVariables=$_GET; 
    552                         $serviceID=null; 
    553                         foreach($paths as $path) 
    554                         { 
    555                                 if(($path=trim($path))!=='') 
    556                                 { 
    557                                         if(($pos=strpos($path,$this->_separator))!==false) 
    558                                         { 
    559                                                 $name=substr($path,0,$pos); 
    560                                                 $value=substr($path,$pos+1); 
    561                                                 if(($pos=strpos($name,'[]'))!==false) 
    562                                                         $getVariables[substr($name,0,$pos)][]=$value; 
    563                                                 else 
    564                                                         $getVariables[$name]=$value; 
    565                                         } 
    566                                         else 
    567                                                 $getVariables[$path]=''; 
    568                                 } 
    569                         } 
    570                         return $getVariables; 
    571                 } 
    572                 else 
    573                         return $_GET; 
     562                return $this->_urlManager->parseUrl(); 
    574563        } 
    575564 
     
    582571         * @see constructUrl 
    583572         */ 
    584         protected function resolveRequest() 
     573        public function resolveRequest() 
    585574        { 
    586575                Prado::trace("Resolving request from ".$_SERVER['REMOTE_ADDR'],'System.Web.THttpRequest'); 
    587576                $this->_requestResolved=true; 
     577                $this->_items=array_merge($_GET,$this->parseUrl(),$_POST); 
    588578                foreach($this->_services as $id) 
    589579                { 
     
    626616        public function getServiceID() 
    627617        { 
    628                 if(!$this->_requestResolved) 
    629                         $this->resolveRequest(); 
    630618                return $this->_serviceID; 
    631619        } 
     
    645633        public function getServiceParameter() 
    646634        { 
    647                 if(!$this->_requestResolved) 
    648                         $this->resolveRequest(); 
    649635                return $this->_serviceParam; 
    650636        } 
  • branches/3.0/framework/Web/TUrlMapping.php

    r1511 r1539  
    1111 */ 
    1212 
     13Prado::using('System.Web.TUrlManager'); 
     14 
    1315/** 
    1416 * TUrlMapping Class 
     
    1820 * before a service is initialized, thus this module should be configured 
    1921 * globally in the <tt>application.xml</tt> file and before any services. 
    20  * 
    21  * The mapping format is as follows. 
    2222 * <code> 
    2323 *  <module id="friendly-url" class="System.Web.TUrlMapping"> 
     
    2626 *    <url ServiceParameter="Posts.ListPost" pattern="category/{cat}/?" parameters.cat="\d+" /> 
    2727 *  </module> 
     28 *  <module id="request" class="THttpRequest" UrlManager="friendly-url" /> 
    2829 * </code> 
    2930 * 
     
    3839 * The mapping can be load from an external file by specifying a configuration 
    3940 * 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. 
    4045 * 
    4146 * @author Wei Zhuo <weizhuo[at]gmail[dot]com> 
     
    4449 * @since 3.0.5 
    4550 */ 
    46 class TUrlMapping extends TModule 
     51class TUrlMapping extends TUrlManager 
    4752{ 
    4853        /** 
     54         * File extension of external configuration file 
     55         */ 
     56        const CONFIG_FILE_EXT='.xml'; 
     57        /** 
    4958         * @var string default pattern class. 
    5059         */ 
     
    5867         */ 
    5968        private $_matched; 
    60         /** 
    61          * File extension of external configuration file 
    62          */ 
    63         const CONFIG_FILE_EXT='.xml'; 
    6469        /** 
    6570         * @var string external configuration file 
     
    7580        public function init($xml) 
    7681        { 
     82                parent::init($xml); 
    7783                if($this->getRequest()->getRequestResolved()) 
    7884                        throw new TConfigurationException('urlpath_dispatch_module_must_be_global'); 
     
    8086                        $this->loadConfigFile(); 
    8187                $this->loadUrlMappings($xml); 
    82                 $this->resolveMappings(); 
    8388        } 
    8489 
     
    143148 
    144149        /** 
    145          * Using the request URL path, find the first matching pattern. If found 
    146          * the matched pattern parameters are used in the Request object. 
    147          */ 
    148         protected function resolveMappings() 
     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() 
    149158        { 
    150159                $url = $this->getRequest()->getUrl(); 
     
    154163                        if(count($matches) > 0) 
    155164                        { 
     165                                $this->_matched=$pattern; 
    156166                                $this->changeServiceParameters($pattern); 
    157                                 $this->initializeRequestParameters($matches); 
    158                                 $this->_matched=$pattern; 
    159                                 break; 
     167                                $params=array(); 
     168                                foreach($matches as $key=>$value) 
     169                                        if(is_string($key)) 
     170                                                $params[$key]=$value; 
     171                                return $params; 
    160172                        } 
    161173                } 
     174                return array(); 
    162175        } 
    163176 
     
    168181        { 
    169182                return $this->_matched; 
    170         } 
    171  
    172         /** 
    173          * @param array initialize the Request with matched parameters. 
    174          */ 
    175         protected function initializeRequestParameters($matches) 
    176         { 
    177                 $request = $this->getRequest(); 
    178                 foreach($matches as $k => $v) 
    179                 { 
    180                         if(!is_int($k)) 
    181                                 $request->add($k,$v); 
    182                 } 
    183183        } 
    184184