diff options
-rw-r--r-- | HISTORY | 4 | ||||
-rw-r--r-- | UPGRADE | 4 | ||||
-rw-r--r-- | framework/Web/THttpRequest.php | 80 | ||||
-rw-r--r-- | framework/Web/UI/TControl.php | 31 | ||||
-rw-r--r-- | framework/Web/UI/TTemplateControl.php | 1 | ||||
-rw-r--r-- | framework/Web/UI/WebControls/TBaseValidator.php | 16 | ||||
-rw-r--r-- | framework/Web/UI/WebControls/TDataGrid.php | 14 | ||||
-rw-r--r-- | framework/Web/UI/WebControls/TDataList.php | 14 | ||||
-rw-r--r-- | framework/Web/UI/WebControls/TRepeater.php | 18 |
9 files changed, 140 insertions, 42 deletions
@@ -16,10 +16,14 @@ BUG: Ticket#264 - Typos in some exception throw statements (Knut) BUG: Ticket#268 - THttpResponse.redirect() may fail for some browsers (Qiang) BUG: TDataGrid may complain getting ItemType on a non-object if the grid is not data-bound (Qiang) BUG: TCheckBox.Value should be converted to string (Qiang) +CHG: Ticket#206 - TBaseValidator.OnValidate is raised only when the validator is visible (Qiang) ENH: Ticket#220 - TClientScripts method to import custom javascript files (Wei) ENH: Ticket#225 - TRadioButton::getRadioButtonsInGroup() added (Wei) ENH: Ticket#223 - Use TRequiredFieldValidator for TRadioButtons with GroupName property (Wei) ENH: Ticket#277 - Added TControl.CustomData property (Qiang) +ENH: Ticket#287 - TControl::broadcastEvent() may raise events now (Qiang) +ENH: Ticket#292 - Added THttpRequest::parseUrl() so that it is easier to be extended (Qiang) +ENH: Better URL 'Path' format (Qiang) NEW: Added TStyleSheet (Wei) Version 3.0.2 July 2, 2006 @@ -16,6 +16,10 @@ for both A and B. Upgrading from v3.0.2
---------------------
+- The signature of TControl::broadcastEvent() is changed from
+ broadcastEvent($sender,TBroadCastEventParameter $param) to
+ broadcastEvent($name,$sender,$param).
+ This makes the call to broadcastEvent() to be consistent with raiseEvent().
Upgrading from v3.0.1
---------------------
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)
{
@@ -524,6 +511,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.
* A URL in the format of /index.php?sp=serviceID.serviceParameter
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 @@ -11,6 +11,11 @@ */ /** + * Using TLabel class + */ +Prado::using('System.Web.UI.WebControls.TLabel'); + +/** * TBaseValidator class * * TBaseValidator serves as the base class for validator controls. @@ -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 <qiang.xue@gmail.com>
* @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 <b>OnCommand</b> 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 <qiang.xue@gmail.com>
* @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 <b>Command</b> event. Therefore,
- * you can handle all sorts of <b>Command</b> event in a central place by
+ * within some repeater item raises a <b>OnCommand</b> event. Therefore,
+ * you can handle all sorts of <b>OnCommand</b> 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 <qiang.xue@gmail.com>
* @version $Revision: $ $Date: $
* @package System.Web.UI.WebControls
|