diff options
Diffstat (limited to 'framework/Web/UI/WebControls')
| -rw-r--r-- | framework/Web/UI/WebControls/TRepeater.php | 510 | 
1 files changed, 510 insertions, 0 deletions
| diff --git a/framework/Web/UI/WebControls/TRepeater.php b/framework/Web/UI/WebControls/TRepeater.php new file mode 100644 index 00000000..af82dfe9 --- /dev/null +++ b/framework/Web/UI/WebControls/TRepeater.php @@ -0,0 +1,510 @@ +<?php
 +/**
 + * TRepeater class file
 + *
 + * @author Qiang Xue <qiang.xue@gmail.com>
 + * @link http://www.pradosoft.com/
 + * @copyright Copyright © 2005 PradoSoft
 + * @license http://www.pradosoft.com/license/
 + * @version $Revision: $  $Date: $
 + * @package System.Web.UI.WebControls
 + */
 +
 +Prado::using('System.Web.UI.WebControls.TDataBoundControl');
 +
 +/**
 + * TRepeater class
 + *
 + * TRepeater displays its content defined in templates repeatedly based on
 + * the <b>DataSource</b> property. The <b>DataSource</b> property only accepts
 + * objects that implement Iterator or IteratorAggregate interface. For convenience,
 + * it also accepts an array.
 + *
 + * The <b>HeaderTemplate</b> property specifies the content template
 + * that will be displayed at the beginning, while <b>FooterTemplate</b> at the last.
 + * If present, these two templates will only be rendered when <b>DataSource</b> is set (not null).
 + * If the <b>DataSource</b> contains item data, then for each item,
 + * the content defined by <b>ItemTemplate</b> will be generated and displayed once.
 + * If <b>AlternatingItemTemplate</b> is not empty, then the corresponding content will
 + * be displayed alternatively with that in <b>ItemTemplate</b>. The content in
 + * <b>SeparatorTemplate</b>, if not empty, will be displayed between two items.
 + * These templates can contain static text, controls and special tags.
 + *
 + * Note, the templates are only parsed and instantiated upon <b>OnDataBinding</b>
 + * event which is raised by calling <b>TControl::dataBind()</b> method. You may
 + * call this method during <b>OnInit</b> or <b>OnLoad</b> life cycles.
 + *
 + * You can retrive the repeated contents by <b>Items</b>.
 + * The number of repeated items is given by <b>ItemCount</b>.
 + *
 + * @author Qiang Xue <qiang.xue@gmail.com>
 + * @version $Revision: $  $Date: $
 + * @package System.Web.UI.WebControls
 + * @since 3.0
 + */
 +class TRepeater extends TDataBoundControl implements INamingContainer
 +{
 +	const CACHE_EXPIRY=18000;
 +	private $_itemTemplate='';
 +	private $_alternatingItemTemplate='';
 +	private $_headerTemplate='';
 +	private $_footerTemplate='';
 +	private $_separatorTemplate='';
 +	private $_emptyTemplate='';
 +	private $_items=null;
 +	private $_header=null;
 +	private $_footer=null;
 +	private static $_templates=array();
 +
 +	/**
 +	 * @return string the template string for the item
 +	 */
 +	public function getItemTemplate()
 +	{
 +		return $this->_itemTemplate;
 +	}
 +
 +	/**
 +	 * Sets the template string for the item
 +	 * @param string the item template
 +	 */
 +	public function setItemTemplate($value)
 +	{
 +		$this->_itemTemplate=$value;
 +	}
 +
 +	/**
 +	 * @return string the template string when there are no items
 +	 */
 +	public function getEmptyTemplate()
 +	{
 +		return $this->_emptyTemplate;
 +	}
 +
 +	/**
 +	 * Sets the template string when there are no items
 +	 * @param string the empty template
 +	 */
 +	public function setEmptyTemplate($value)
 +	{
 +		$this->_emptyTemplate=$value;
 +	}
 +	/**
 +	 * @return string the alternative template string for the item
 +	 */
 +	public function getAlternatingItemTemplate()
 +	{
 +		return $this->_alternatingItemTemplate;
 +	}
 +
 +	/**
 +	 * Sets the alternative template string for the item
 +	 * @param string the alternative item template
 +	 */
 +	public function setAlternatingItemTemplate($value)
 +	{
 +		$this->_alternatingItemTemplate=$value;
 +	}
 +
 +	/**
 +	 * @return string the header template string
 +	 */
 +	public function getHeaderTemplate()
 +	{
 +		return $this->_headerTemplate;
 +	}
 +
 +	/**
 +	 * Sets the header template.
 +	 * The template will be parsed immediately.
 +	 * @param string the header template
 +	 */
 +	public function setHeaderTemplate($value)
 +	{
 +		$this->_headerTemplate=$value;
 +	}
 +
 +	/**
 +	 * @return string the footer template string
 +	 */
 +	public function getFooterTemplate()
 +	{
 +		return $this->_footerTemplate;
 +	}
 +
 +	/**
 +	 * Sets the footer template.
 +	 * The template will be parsed immediately.
 +	 * @param string the footer template
 +	 */
 +	public function setFooterTemplate($value)
 +	{
 +		$this->_footerTemplate=$value;
 +	}
 +
 +	/**
 +	 * @return string the separator template string
 +	 */
 +	public function getSeparatorTemplate()
 +	{
 +		return $this->_separatorTemplate;
 +	}
 +
 +	/**
 +	 * Sets the separator template string
 +	 * @param string the separator template
 +	 */
 +	public function setSeparatorTemplate($value)
 +	{
 +		$this->_separatorTemplate=$value;
 +	}
 +
 +	/**
 +	 * @return TRepeaterItem the header item
 +	 */
 +	public function getHeader()
 +	{
 +		return $this->_header;
 +	}
 +
 +	/**
 +	 * @return TRepeaterItem the footer item
 +	 */
 +	public function getFooter()
 +	{
 +		return $this->_footer;
 +	}
 +
 +	/**
 +	 * @return array list of TRepeaterItem control
 +	 */
 +	public function getItems()
 +	{
 +		if(!$this->_items)
 +			$this->_items=new TList;
 +		return $this->_items;
 +	}
 +
 +	protected function createItem($itemIndex,$itemType)
 +	{
 +		return new TRepeaterItem($itemIndex,$itemType);
 +	}
 +
 +	protected function initializeItem($item)
 +	{
 +		$tplContent='';
 +		switch($item->getItemType())
 +		{
 +			case 'Header': $tplContent=$this->_headerTemplate; break;
 +			case 'Footer': $tplContent=$this->_footerTemplate; break;
 +			case 'Item': $tplContent=$this->_itemTemplate; break;
 +			case 'Separator': $tplContent=$this->_separatorTemplate; break;
 +			case 'AlternatingItem': $tplContent=$this->_alternatingItemTemplate==='' ? $this->_itemTemplate : $this->_alternatingItemTemplate; break;
 +			case 'SelectedItem':
 +			case 'EditItem':
 +			default:
 +				break;
 +		}
 +		if($tplContent!=='')
 +		{
 +			$key=md5($tplContent);
 +			$contextPath=$this->getTemplateControl()->getTemplate()->getContextPath();
 +			if(($cache=$this->getApplication()->getCache())!==null)
 +			{
 +				if(($template=$cache->get($key))===null)
 +				{
 +					$template=new TTemplate($tplContent,$contextPath);
 +					$cache->set($key,$template,self::CACHE_EXPIRY);
 +				}
 +			}
 +			else
 +			{
 +				if(isset(self::$_templates[$key]))
 +					$template=self::$_templates[$key];
 +				else
 +				{
 +					$template=new TTemplate($tplContent,$contextPath);
 +					self::$_templates[$key]=$template;
 +				}
 +			}
 +			$this->getControls()->add($item);
 +			$template->instantiateIn($item);
 +		}
 +	}
 +
 +	private function createItemInternal($itemIndex,$itemType,$dataBind,$dataItem)
 +	{
 +		$item=$this->createItem($itemIndex,$itemType);
 +		$this->initializeItem($item);
 +		$param=new TRepeaterItemEventParameter($item);
 +		if($dataBind)
 +		{
 +			$item->setDataItem($dataItem);
 +			$this->onItemCreated($param);
 +			$item->dataBind();
 +			$this->onItemDataBound($param);
 +			$item->setDataItem(null);
 +		}
 +		else
 +			$this->onItemCreated($param);
 +		return $item;
 +	}
 +
 +	protected function createChildControls()
 +	{
 +		$this->getControls()->clear();
 +		$items=$this->getItems();
 +		$items->clear();
 +		$this->_header=null;
 +		$this->_footer=null;
 +		if(($itemCount=$this->getViewState('ItemCount',null))!==null)
 +		{
 +			if($this->_headerTemplate!=='')
 +				$this->_header=$this->createItemInternal(-1,'Header',false,null);
 +			$hasSeparator=$this->_separatorTemplate!=='';
 +			for($i=0;$i<$itemCount;++$i)
 +			{
 +				if($hasSeparator && $i>0)
 +					$this->createItemInternal($i-1,'Separator',false,null);
 +				$itemType=$i%2==0?'Item':'AlternatingItem';
 +				$items->add($this->createItemInternal($i,$itemType,false,null));
 +			}
 +			if($this->_footerTemplate!=='')
 +				$this->_footer=$this->createItemInternal(-1,'Footer',false,null);
 +		}
 +		$this->clearChildState();
 +	}
 +
 +	/**
 +	 * Performs databinding to populate list items from data source.
 +	 * This method is invoked by dataBind().
 +	 * You may override this function to provide your own way of data population.
 +	 * @param Traversable the data
 +	 */
 +	protected function performDataBinding($data)
 +	{
 +		$this->getControls()->clear();
 +		$this->clearChildState();
 +		$items=$this->getItems();
 +		$items->clear();
 +		$itemIndex=0;
 +		if($data!==null)
 +		{
 +			if($this->_headerTemplate!=='')
 +				$this->_header=$this->createItemInternal(-1,'Header',true,null);
 +			$hasSeparator=$this->_separatorTemplate!=='';
 +			foreach($data as $dataItem)
 +			{
 +				if($hasSeparator && $itemIndex>0)
 +					$this->createItemInternal($itemIndex-1,'Separator',true,null);
 +				$itemType=$itemIndex%2==0?'Item':'AlternatingItem';
 +				$items->add($this->createItemInternal($itemIndex,$itemType,true,$dataItem));
 +				$itemIndex++;
 +			}
 +			if($this->_footerTemplate!=='')
 +				$this->_footer=$this->createItemInternal(-1,'Footer',true,null);
 +			$this->setViewState('ItemCount',$itemIndex,0);
 +		}
 +		else
 +			$this->setViewState('ItemCount',$itemIndex,-1);
 +		$this->setChildControlsCreated(true);
 +	}
 +
 +	/**
 +	 * Raises <b>OnItemCreated</b> event.
 +	 * This method is invoked after a repeater item is created.
 +	 * You may override this method to provide customized event handling.
 +	 * Be sure to call parent's implementation so that
 +	 * event handlers have chance to respond to the event.
 +	 * The TRepeaterItem control responsible for the event
 +	 * can be determined from the event parameter's <b>item</b>
 +	 * field.
 +	 * @param TRepeaterItemEventParameter event parameter
 +	 */
 +	protected function onItemCreated($param)
 +	{
 +		$this->raiseEvent('ItemCreated',$this,$param);
 +	}
 +
 +	/**
 +	 * Handles <b>OnBubbleEvent</b>.
 +	 * This method overrides parent's implementation to handle
 +	 * <b>OnItemCommand</b> event that is bubbled from
 +	 * TRepeaterItem child controls.
 +	 * This method should only be used by control developers.
 +	 * @param TControl the sender of the event
 +	 * @param TEventParameter event parameter
 +	 * @return boolean whether the event bubbling should stop here.
 +	 */
 +	protected function onBubbleEvent($sender,$param)
 +	{
 +		if($param instanceof TRepeaterCommandEventParameter)
 +		{
 +			$this->onItemCommand($param);
 +			return true;
 +		}
 +		else
 +			return false;
 +	}
 +
 +	/**
 +	 * Raises <b>OnItemCommand</b> event.
 +	 * This method is invoked after a button control in
 +	 * a template raises <b>OnCommand</b> event.
 +	 * You may override this method to provide customized event handling.
 +	 * Be sure to call parent's implementation so that
 +	 * event handlers have chance to respond to the event.
 +	 * The TRepeaterItem control responsible for the event
 +	 * can be determined from the event parameter's <b>item</b>
 +	 * field. The initial sender of the <b>OnCommand</b> event
 +	 * is in <b>source</b> field. The command name and parameter
 +	 * are in <b>name</b> and <b>parameter</b> fields, respectively.
 +	 * @param TRepeaterCommandEventParameter event parameter
 +	 */
 +	protected function onItemCommand($param)
 +	{
 +		$this->raiseEvent('ItemCommand',$this,$param);
 +	}
 +
 +	protected function onItemDataBound($param)
 +	{
 +		$this->raiseEvent('ItemDataBound',$this,$param);
 +	}
 +}
 +
 +/**
 + * TRepeaterItemEventParameter class
 + *
 + * TRepeaterItemEventParameter encapsulates the parameter data for <b>OnItemCreated</b>
 + * event of TRepeater controls.
 + *
 + * @author Qiang Xue <qiang.xue@gmail.com>
 + * @version v1.0, last update on 2004/08/13 21:44:52
 + * @package System.Web.UI.WebControls
 + */
 +class TRepeaterItemEventParameter extends TEventParameter
 +{
 +	/**
 +	 * The TRepeaterItem control responsible for the event.
 +	 * @var TRepeaterItem
 +	 */
 +	public $_item=null;
 +
 +	public function __construct(TRepeaterItem $item)
 +	{
 +		$this->_item=$item;
 +	}
 +
 +	public function getItem()
 +	{
 +		return $this->_item;
 +	}
 +}
 +
 +/**
 + * TRepeaterCommandEventParameter class
 + *
 + * TRepeaterCommandEventParameter encapsulates the parameter data for <b>OnItemCommand</b>
 + * event of TRepeater controls.
 + *
 + * @author Qiang Xue <qiang.xue@gmail.com>
 + * @version v1.0, last update on 2004/08/13 21:44:52
 + * @package System.Web.UI.WebControls
 + */
 +class TRepeaterCommandEventParameter extends TCommandEventParameter
 +{
 +	/**
 +	 * The TRepeaterItem control responsible for the event.
 +	 * @var TRepeaterItem
 +	 */
 +	public $_item=null;
 +	/**
 +	 * The control originally raises the <b>Command</b> event.
 +	 * @var TControl
 +	 */
 +	public $_source=null;
 +
 +	public function __construct($item,$source,TCommandEventParameter $param)
 +	{
 +		$this->_item=$item;
 +		$this->_source=$source;
 +		parent::__construct($param->getCommandName(),$param->getCommandParameter());
 +	}
 +
 +	public function getItem()
 +	{
 +		return $this->_item;
 +	}
 +
 +	public function getCommandSource()
 +	{
 +		return $this->_source;
 +	}
 +}
 +
 +class TRepeaterItem extends TControl implements INamingContainer
 +{
 +	/**
 +	 * index of the data item in the Items collection of repeater
 +	 */
 +	private $_itemIndex='';
 +	/**
 +	 * type of the TRepeaterItem
 +	 * @var string
 +	 */
 +	private $_itemType='';
 +	/**
 +	 * value of the data item
 +	 * @var mixed
 +	 */
 +	private $_dataItem=null;
 +
 +	public function __construct($itemIndex,$itemType)
 +	{
 +		$this->_itemIndex=$itemIndex;
 +		$this->_itemType=TPropertyValue::ensureEnum($itemType,'Header','Footer','Item','AlternatingItem','SelectedItem','EditItem','Separator','Pager');
 +	}
 +
 +	public function getItemType()
 +	{
 +		return $this->_itemType;
 +	}
 +
 +	public function getItemIndex()
 +	{
 +		return $this->_itemIndex;
 +	}
 +
 +	public function getDataItem()
 +	{
 +		return $this->_dataItem;
 +	}
 +
 +	public function setDataItem($value)
 +	{
 +		$this->_dataItem=$value;
 +	}
 +
 +	/**
 +	 * Handles <b>OnBubbleEvent</b>.
 +	 * This method overrides parent's implementation to bubble
 +	 * <b>OnItemCommand</b> event if an <b>OnCommand</b>
 +	 * event is bubbled from a child control.
 +	 * This method should only be used by control developers.
 +	 * @param TControl the sender of the event
 +	 * @param TEventParameter event parameter
 +	 * @return boolean whether the event bubbling should stop here.
 +	 */
 +	protected function onBubbleEvent($sender,$param)
 +	{
 +		if($param instanceof TCommandEventParameter)
 +		{
 +			$this->raiseBubbleEvent($this,new TRepeaterCommandEventParameter($this,$sender,$param));
 +			return true;
 +		}
 +		else
 +			return false;
 +	}
 +}
 +
 +?>
\ No newline at end of file | 
