From c0d9d27f16bae2e428225302da144e9cc6d4adc8 Mon Sep 17 00:00:00 2001 From: xue <> Date: Fri, 21 Jul 2006 16:14:01 +0000 Subject: merge from 3.0 branch till 1281. --- framework/Web/THttpRequest.php | 80 +++++++++++++++++-------- framework/Web/UI/TControl.php | 31 ++++++---- framework/Web/UI/TTemplateControl.php | 1 - framework/Web/UI/WebControls/TBaseValidator.php | 16 +++-- framework/Web/UI/WebControls/TDataGrid.php | 14 +++++ framework/Web/UI/WebControls/TDataList.php | 14 +++++ framework/Web/UI/WebControls/TRepeater.php | 18 +++++- 7 files changed, 132 insertions(+), 42 deletions(-) (limited to 'framework') diff --git a/framework/Web/THttpRequest.php b/framework/Web/THttpRequest.php index b908db53..323a4b7c 100644 --- a/framework/Web/THttpRequest.php +++ b/framework/Web/THttpRequest.php @@ -162,27 +162,7 @@ class THttpRequest extends TApplicationComponent implements IteratorAggregate,Ar } if($this->getUrlFormat()==='Path' && ($pathInfo=trim($this->_pathInfo,'/'))!=='') - { - $paths=explode('/',$pathInfo); - foreach($paths as $path) - { - if(($path=trim($path))!=='') - { - if(($pos=strpos($path,','))!==false) - { - $name=substr($path,0,$pos); - $value=substr($path,$pos+1); - if(($pos=strpos($name,'[]'))!==false) - $getVariables[substr($name,0,$pos)][]=$value; - else - $getVariables[$name]=$value; - } - else - $getVariables[$path]=''; - } - } - $this->_items=array_merge($getVariables,array_merge($_GET,$_POST)); - } + $this->_items=array_merge($this->parseUrl(),$_POST); else $this->_items=array_merge($_GET,$_POST); @@ -293,7 +273,7 @@ class THttpRequest extends TApplicationComponent implements IteratorAggregate,Ar { return ($this->getIsSecureConnection() ? "https://" : "http://") . $_SERVER ['HTTP_HOST']; } - + /** * @return string entry script URL (w/o host part) */ @@ -309,7 +289,7 @@ class THttpRequest extends TApplicationComponent implements IteratorAggregate,Ar { return $this->getBaseUrl() . $this->getApplicationUrl(); } - + /** * @return string application entry script file path (processed w/ realpath()) */ @@ -465,18 +445,25 @@ class THttpRequest extends TApplicationComponent implements IteratorAggregate,Ar /** * Constructs a URL that is recognizable by Prado. * You may override this method to provide your own way of URL formatting. + * If you do so, you may also need to override {@link parseUrl} so that the URL can be properly parsed. * The URL is constructed as the following format: * /entryscript.php?serviceID=serviceParameter&get1=value1&... + * If {@link setUrlFormat UrlFormat} is 'Path', the following format is used instead: + * /entryscript.php/serviceID/serviceParameter/get1,value1/get2,value2... * @param string service ID * @param string service parameter * @param array GET parameters, null if not needed * @param boolean whether to encode the ampersand in URL, defaults to false. * @param boolean whether to encode the GET parameters (their names and values), defaults to true. * @return string URL + * @see parseUrl */ public function constructUrl($serviceID,$serviceParam,$getItems=null,$encodeAmpersand=false,$encodeGetItems=true) { - $url=$serviceID.'='.$serviceParam; + if($this->getUrlFormat()==='Path') + $url=$serviceID.'/'.$serviceParam; + else + $url=$serviceID.'='.$serviceParam; $amp=$encodeAmpersand?'&':'&'; if(is_array($getItems) || $getItems instanceof Traversable) { @@ -523,6 +510,51 @@ class THttpRequest extends TApplicationComponent implements IteratorAggregate,Ar } } + /** + * Parses the request URL and returns an array of input parameters (including GET variables). + * This method is invoked when the URL format is 'Path'. + * You may override this method to support customized URL format. + * @return array list of input parameters, indexed by parameter names + * @see constructUrl + */ + protected function parseUrl() + { + if($this->_pathInfo!=='') + { + $paths=explode('/',$this->_pathInfo); + $getVariables=$_GET; + $index=0; + $serviceID=null; + foreach($paths as $path) + { + if(($path=trim($path))!=='') + { + if(($pos=strpos($path,','))!==false) + { + $name=substr($path,0,$pos); + $value=substr($path,$pos+1); + if(($pos=strpos($name,'[]'))!==false) + $getVariables[substr($name,0,$pos)][]=$value; + else + $getVariables[$name]=$value; + } + else if($index===0) + { + $serviceID=$path; + $getVariables[$serviceID]=''; + } + else if($index===1 && $serviceID!==null) + $getVariables[$serviceID]=$path; + else + $getVariables[$path]=''; + } + } + return $getVariables; + } + else + return $_GET; + } + /** * Resolves the requested servie. * This method implements a URL-based service resolution. diff --git a/framework/Web/UI/TControl.php b/framework/Web/UI/TControl.php index aa8ea2a3..2bc6ba6a 100644 --- a/framework/Web/UI/TControl.php +++ b/framework/Web/UI/TControl.php @@ -1423,27 +1423,36 @@ class TControl extends TApplicationComponent implements IRenderable, IBindable /** * Broadcasts an event. * The event will be sent to all controls on the current page hierarchy. - * If this control is not on a page, the event will be sent to all its - * child controls recursively. - * Controls implementing {@link IBroadcastEventReceiver} will get a chance - * to respond to the event. - * @param TControl sender of the event - * @param TBroadcastEventParameter event parameter + * If a control defines the event, the event will be raised for the control. + * If a control implements {@link IBroadcastEventReceiver}, its + * {@link IBroadcastEventReceiver::broadcastEventReceived broadcastEventReceived()} method will + * be invoked which gives the control a chance to respond to the event. + * For example, when broadcasting event 'OnClick', all controls having 'OnClick' + * event will have this event raised, and all controls implementing + * {@link IBroadcastEventReceiver} will also have its + * {@link IBroadcastEventReceiver::broadcastEventReceived broadcastEventReceived()} + * invoked. + * @param string name of the broadcast event + * @param TControl sender of this event + * @param TEventParameter event parameter */ - protected function broadcastEvent($sender,TBroadCastEventParameter $param) + public function broadcastEvent($name,$sender,$param) { - $origin=(($page=$this->getPage())===null)?$this:$page; - $origin->broadcastEventInternal($sender,$param); + $rootControl=(($page=$this->getPage())===null)?$this:$page; + $rootControl->broadcastEventInternal($name,$sender,new TBroadcastEventParameter($name,$param)); } /** * Recursively broadcasts an event. * This method should only be used by framework developers. + * @param string name of the broadcast event * @param TControl sender of the event * @param TBroadcastEventParameter event parameter */ - final protected function broadcastEventInternal($sender,$param) + private function broadcastEventInternal($name,$sender,$param) { + if($this->hasEvent($name)) + $this->raiseEvent($name,$sender,$param->getParameter()); if($this instanceof IBroadcastEventReceiver) $this->broadcastEventReceived($sender,$param); if($this->getHasControls()) @@ -1451,7 +1460,7 @@ class TControl extends TApplicationComponent implements IRenderable, IBindable foreach($this->_rf[self::RF_CONTROLS] as $control) { if($control instanceof TControl) - $control->broadcastEventInternal($sender,$param); + $control->broadcastEventInternal($name,$sender,$param); } } } diff --git a/framework/Web/UI/TTemplateControl.php b/framework/Web/UI/TTemplateControl.php index 0595a9e5..c7364d4b 100644 --- a/framework/Web/UI/TTemplateControl.php +++ b/framework/Web/UI/TTemplateControl.php @@ -119,7 +119,6 @@ class TTemplateControl extends TCompositeControl { Prado::trace("Loading template ".get_class($this),'System.Web.UI.TTemplateControl'); $template=$this->getService()->getTemplateManager()->getTemplateByClassName(get_class($this)); - self::$_template[get_class($this)]=$template; return $template; } diff --git a/framework/Web/UI/WebControls/TBaseValidator.php b/framework/Web/UI/WebControls/TBaseValidator.php index 9366de62..6660184e 100644 --- a/framework/Web/UI/WebControls/TBaseValidator.php +++ b/framework/Web/UI/WebControls/TBaseValidator.php @@ -10,6 +10,11 @@ * @package System.Web.UI.WebControls */ +/** + * Using TLabel class + */ +Prado::using('System.Web.UI.WebControls.TLabel'); + /** * TBaseValidator class * @@ -474,10 +479,10 @@ abstract class TBaseValidator extends TLabel implements IValidator */ public function validate() { - $this->onValidate(); + if($visible=$this->getVisible(true)) + $this->onValidate(); $this->setIsValid(true); - $control=$this->getValidationTarget(); - if($control && $this->getVisible(true) && $this->getEnabled()) + if($this->getValidationTarget() && $visible && $this->getEnabled()) { if($this->evaluateIsValid()) { @@ -534,6 +539,9 @@ abstract class TBaseValidator extends TLabel implements IValidator /** * This event is raised right before the validator starts to perform validation. + * You may use this event to change the behavior of validation. + * For example, you may disable the validator if certain condition is satisfied. + * Note, the event will NOT be raised if the validator is invisible. */ public function onValidate() { @@ -666,4 +674,4 @@ class TClientSideValidatorOptions extends TClientSideOptions } } -?> +?> \ No newline at end of file diff --git a/framework/Web/UI/WebControls/TDataGrid.php b/framework/Web/UI/WebControls/TDataGrid.php index f7697fec..2687ac35 100644 --- a/framework/Web/UI/WebControls/TDataGrid.php +++ b/framework/Web/UI/WebControls/TDataGrid.php @@ -43,6 +43,12 @@ Prado::using('System.Web.UI.WebControls.TPanel'); * To change the state of an item, set {@link setEditItemIndex EditItemIndex} * or {@link setSelectedItemIndex SelectedItemIndex} property. * + * Each datagrid item has a {@link TDataGridItem::getItemType type} + * which tells the position and state of the item in the datalist. An item in the header + * of the repeater is of type 'Header'. A body item may be of either + * 'Item', 'AlternatingItem', 'SelectedItem' or 'EditItem', depending whether the item + * index is odd or even, whether it is being selected or edited. + * * A datagrid is specified with a list of columns. Each column specifies how the corresponding * table column will be displayed. For example, the header/footer text of that column, * the cells in that column, and so on. The following column types are currently @@ -128,6 +134,14 @@ Prado::using('System.Web.UI.WebControls.TPanel'); * every newly created datagrid item. You can respond to this event to customize * the content or style of the newly created item. * + * Note, the data bound to the datagrid are reset to null after databinding. + * There are several ways to access the data associated with a datagrid row: + * - Access the data in {@link onItemDataBound OnItemDataBound} event + * - Use {@link getDataKeys DataKeys} to obtain the data key associated with + * the specified datagrid row and use the key to fetch the corresponding data + * from some persistent storage such as DB. + * - Save the data in viewstate and get it back during postbacks. + * * @author Qiang Xue * @version $Revision: $ $Date: $ * @package System.Web.UI.WebControls diff --git a/framework/Web/UI/WebControls/TDataList.php b/framework/Web/UI/WebControls/TDataList.php index 2c562d6d..42c47f86 100644 --- a/framework/Web/UI/WebControls/TDataList.php +++ b/framework/Web/UI/WebControls/TDataList.php @@ -85,12 +85,26 @@ Prado::using('System.Web.UI.WebControls.TRepeatInfo'); * event will be raised. Note, the selected index may not be actually changed. * The event mainly informs the server side that the end-user has made a selection. * + * Each datalist item has a {@link TDataListItem::getItemType type} + * which tells the position and state of the item in the datalist. An item in the header + * of the repeater is of type 'Header'. A body item may be of either + * 'Item', 'AlternatingItem', 'SelectedItem' or 'EditItem', depending whether the item + * index is odd or even, whether it is being selected or edited. + * * TDataList raises an {@link onItemCommand OnItemCommand} whenever a button control * within some TDataList item raises a OnCommand event. If the command name * is one of the followings: 'edit', 'update', 'select', 'delete', 'cancel' (case-insensitive), * another event will also be raised. For example, if the command name is 'edit', * then the new event is {@link onEditCommand OnEditCommand}. * + * Note, the data bound to the datalist are reset to null after databinding. + * There are several ways to access the data associated with a datalist item: + * - Access the data in {@link onItemDataBound OnItemDataBound} event + * - Use {@link getDataKeys DataKeys} to obtain the data key associated with + * the specified datalist item and use the key to fetch the corresponding data + * from some persistent storage such as DB. + * - Save the data in viewstate and get it back during postbacks. + * * @author Qiang Xue * @version $Revision: $ $Date: $ * @package System.Web.UI.WebControls diff --git a/framework/Web/UI/WebControls/TRepeater.php b/framework/Web/UI/WebControls/TRepeater.php index eb599341..01c88a30 100644 --- a/framework/Web/UI/WebControls/TRepeater.php +++ b/framework/Web/UI/WebControls/TRepeater.php @@ -36,6 +36,12 @@ Prado::using('System.Util.TDataFieldAccessor'); * {@link setSeparatorTemplate SeparatorTemplate}, if not empty, will be * displayed between items. * + * Each repeater item has a {@link TRepeaterItem::getItemType type} + * which tells the position of the item in the repeater. An item in the header + * of the repeater is of type TRepeater::IT_HEADER. A body item may be of either + * TRepeater::IT_ITEM or TRepeater::IT_ALTERNATINGITEM, depending whether the item + * index is odd or even. + * * You can retrive the repeated contents by the {@link getItems Items} property. * The header and footer items can be accessed by {@link getHeader Header} * and {@link getFooter Footer} properties, respectively. @@ -46,10 +52,18 @@ Prado::using('System.Util.TDataFieldAccessor'); * databinding, an {@link onItemDataBound OnItemDataBound} event will be raised. * * TRepeater raises an {@link onItemCommand OnItemCommand} whenever a button control - * within some repeater item raises a Command event. Therefore, - * you can handle all sorts of Command event in a central place by + * within some repeater item raises a OnCommand event. Therefore, + * you can handle all sorts of OnCommand event in a central place by * writing an event handler for {@link onItemCommand OnItemCommand}. * + * Note, the data bound to the repeater are reset to null after databinding. + * There are several ways to access the data associated with a repeater item: + * - Access the data in {@link onItemDataBound OnItemDataBound} event + * - Use {@link getDataKeys DataKeys} to obtain the data key associated with + * the specified repeater item and use the key to fetch the corresponding data + * from some persistent storage such as DB. + * - Save the data in viewstate and get it back during postbacks. + * * @author Qiang Xue * @version $Revision: $ $Date: $ * @package System.Web.UI.WebControls -- cgit v1.2.3