[ Index ]
 

Code source de PRADO 3.0.6

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/framework/Web/UI/WebControls/ -> TDataBoundControl.php (source)

   1  <?php
   2  /**
   3   * TDataBoundControl class file
   4   *
   5   * @author Qiang Xue <qiang.xue@gmail.com>
   6   * @link http://www.pradosoft.com/
   7   * @copyright Copyright &copy; 2005 PradoSoft
   8   * @license http://www.pradosoft.com/license/
   9   * @version $Id: TDataBoundControl.php 1533 2006-12-01 12:37:06Z xue $
  10   * @package System.Web.UI.WebControls
  11   */
  12  
  13  Prado::using('System.Web.UI.WebControls.TDataSourceControl');
  14  Prado::using('System.Web.UI.WebControls.TDataSourceView');
  15  Prado::using('System.Collections.TPagedDataSource');
  16  
  17  /**
  18   * TDataBoundControl class.
  19   *
  20   * TDataBoundControl is the based class for controls that need to populate
  21   * data from data sources. It provides basic properties and methods that allow
  22   * the derived controls to associate with data sources and retrieve data from them.
  23   *
  24   * TBC....
  25   *
  26   * TDataBoundControl is equipped with paging capabilities. By setting
  27   * {@link setAllowPaging AllowPaging} to true, the input data will be paged
  28   * and only one page of data is actually populated into the data-bound control.
  29   * This saves a lot of memory when dealing with larget datasets.
  30   *
  31   * To specify the number of data items displayed on each page, set
  32   * the {@link setPageSize PageSize} property, and to specify which
  33   * page of data to be displayed, set {@link setCurrentPageIndex CurrentPageIndex}.
  34   *
  35   * When the size of the original data is too big to be loaded all in the memory,
  36   * one can enable custom paging. In custom paging, the total number of data items
  37   * is specified manually via {@link setVirtualItemCount VirtualItemCount},
  38   * and the data source only needs to contain the current page of data. To enable
  39   * custom paging, set {@link setAllowCustomPaging AllowCustomPaging} to true.
  40   *
  41   * @author Qiang Xue <qiang.xue@gmail.com>
  42   * @version $Id: TDataBoundControl.php 1533 2006-12-01 12:37:06Z xue $
  43   * @package System.Web.UI.WebControls
  44   * @since 3.0
  45   */
  46  abstract class TDataBoundControl extends TWebControl
  47  {
  48      private $_initialized=false;
  49      private $_dataSource=null;
  50      private $_requiresBindToNull=false;
  51      private $_requiresDataBinding=false;
  52      private $_prerendered=false;
  53      private $_currentView=null;
  54      private $_currentDataSource=null;
  55      private $_currentViewValid=false;
  56      private $_currentDataSourceValid=false;
  57      private $_currentViewIsFromDataSourceID=false;
  58      private $_parameters=null;
  59      private $_isDataBound=false;
  60  
  61      /**
  62       * @return Traversable data source object, defaults to null.
  63       */
  64  	public function getDataSource()
  65      {
  66          return $this->_dataSource;
  67      }
  68  
  69      /**
  70       * Sets the data source object associated with the databound control.
  71       * The data source must implement Traversable interface.
  72       * If an array is given, it will be converted to xxx.
  73       * If a string is given, it will be converted to xxx.
  74       * @param Traversable|array|string data source object
  75       */
  76  	public function setDataSource($value)
  77      {
  78          $this->_dataSource=$this->validateDataSource($value);
  79          $this->onDataSourceChanged();
  80      }
  81  
  82      /**
  83       * @return string ID path to the data source control. Defaults to empty.
  84       */
  85  	public function getDataSourceID()
  86      {
  87          return $this->getViewState('DataSourceID','');
  88      }
  89  
  90      /**
  91       * @param string ID path to the data source control. The data source
  92       * control must be locatable via {@link TControl::findControl} call.
  93       */
  94  	public function setDataSourceID($value)
  95      {
  96          $dsid=$this->getViewState('DataSourceID','');
  97          if($dsid!=='' && $value==='')
  98              $this->_requiresBindToNull=true;
  99          $this->setViewState('DataSourceID',$value,'');
 100          $this->onDataSourceChanged();
 101      }
 102  
 103      /**
 104       * @return boolean if the databound control uses the data source specified
 105       * by {@link setDataSourceID}, or it uses the data source object specified
 106       * by {@link setDataSource}.
 107       */
 108  	protected function getUsingDataSourceID()
 109      {
 110          return $this->getDataSourceID()!=='';
 111      }
 112  
 113      /**
 114       * Sets {@link setRequiresDataBinding RequiresDataBinding} as true if the control is initialized.
 115       * This method is invoked when either {@link setDataSource} or {@link setDataSourceID} is changed.
 116       */
 117  	public function onDataSourceChanged()
 118      {
 119          $this->_currentViewValid=false;
 120          $this->_currentDataSourceValid=false;
 121          if($this->getInitialized())
 122              $this->setRequiresDataBinding(true);
 123      }
 124  
 125      /**
 126       * @return boolean whether the databound control has been initialized.
 127       * By default, the control is initialized after its viewstate has been restored.
 128       */
 129  	protected function getInitialized()
 130      {
 131          return $this->_initialized;
 132      }
 133  
 134      /**
 135       * Sets a value indicating whether the databound control is initialized.
 136       * If initialized, any modification to {@link setDataSource DataSource} or
 137       * {@link setDataSourceID DataSourceID} will set {@link setRequiresDataBinding RequiresDataBinding}
 138       * as true.
 139       * @param boolean a value indicating whether the databound control is initialized.
 140       */
 141  	protected function setInitialized($value)
 142      {
 143          $this->_initialized=TPropertyValue::ensureBoolean($value);
 144      }
 145  
 146      /**
 147       * @return boolean whether databind has been invoked in the previous page request
 148       */
 149  	protected function getIsDataBound()
 150      {
 151          return $this->_isDataBound;
 152      }
 153  
 154      /**
 155       * @param boolean if databind has been invoked in this page request
 156       */
 157  	protected function setIsDataBound($value)
 158      {
 159          $this->_isDataBound=$value;
 160      }
 161  
 162      /**
 163       * @return boolean whether a databind call is required (by the data bound control)
 164       */
 165  	protected function getRequiresDataBinding()
 166      {
 167          return $this->_requiresDataBinding;
 168      }
 169  
 170      /**
 171       * @return boolean whether paging is enabled. Defaults to false.
 172       */
 173  	public function getAllowPaging()
 174      {
 175          return $this->getViewState('AllowPaging',false);
 176      }
 177  
 178      /**
 179       * @param boolean whether paging is enabled
 180       */
 181  	public function setAllowPaging($value)
 182      {
 183          $this->setViewState('AllowPaging',TPropertyValue::ensureBoolean($value),false);
 184      }
 185  
 186      /**
 187       * @return boolean whether the custom paging is enabled. Defaults to false.
 188       */
 189  	public function getAllowCustomPaging()
 190      {
 191          return $this->getViewState('AllowCustomPaging',false);
 192      }
 193  
 194      /**
 195       * Sets a value indicating whether the custom paging should be enabled.
 196       * When the pager is in custom paging mode, the {@link setVirtualItemCount VirtualItemCount}
 197       * property is used to determine the paging, and the data items in the
 198       * {@link setDataSource DataSource} are considered to be in the current page.
 199       * @param boolean whether the custom paging is enabled
 200       */
 201  	public function setAllowCustomPaging($value)
 202      {
 203          $this->setViewState('AllowCustomPaging',TPropertyValue::ensureBoolean($value),false);
 204      }
 205  
 206      /**
 207       * @return integer the zero-based index of the current page. Defaults to 0.
 208       */
 209  	public function getCurrentPageIndex()
 210      {
 211          return $this->getViewState('CurrentPageIndex',0);
 212      }
 213  
 214      /**
 215       * @param integer the zero-based index of the current page
 216       * @throws TInvalidDataValueException if the value is less than 0
 217       */
 218  	public function setCurrentPageIndex($value)
 219      {
 220          if(($value=TPropertyValue::ensureInteger($value))<0)
 221              $value=0;
 222          $this->setViewState('CurrentPageIndex',$value,0);
 223      }
 224  
 225      /**
 226       * @return integer the number of data items on each page. Defaults to 10.
 227       */
 228  	public function getPageSize()
 229      {
 230          return $this->getViewState('PageSize',10);
 231      }
 232  
 233      /**
 234       * @param integer the number of data items on each page.
 235       * @throws TInvalidDataValueException if the value is less than 1
 236       */
 237  	public function setPageSize($value)
 238      {
 239          if(($value=TPropertyValue::ensureInteger($value))<1)
 240              throw new TInvalidDataValueException('databoundcontrol_pagesize_invalid',get_class($this));
 241          $this->setViewState('PageSize',TPropertyValue::ensureInteger($value),10);
 242      }
 243  
 244      /**
 245       * @return integer number of pages of data items available
 246       */
 247  	public function getPageCount()
 248      {
 249          return $this->getViewState('PageCount',1);
 250      }
 251  
 252      /**
 253       * @return integer virtual number of data items in the data source. Defaults to 0.
 254       * @see setAllowCustomPaging
 255       */
 256  	public function getVirtualItemCount()
 257      {
 258          return $this->getViewState('VirtualItemCount',0);
 259      }
 260  
 261      /**
 262       * @param integer virtual number of data items in the data source.
 263       * @throws TInvalidDataValueException if the value is less than 0
 264       * @see setAllowCustomPaging
 265       */
 266  	public function setVirtualItemCount($value)
 267      {
 268          if(($value=TPropertyValue::ensureInteger($value))<0)
 269              throw new TInvalidDataValueException('databoundcontrol_virtualitemcount_invalid',get_class($this));
 270          $this->setViewState('VirtualItemCount',$value,0);
 271      }
 272  
 273      /**
 274       * Sets a value indicating whether a databind call is required by the data bound control.
 275       * If true and the control has been prerendered while it uses the data source
 276       * specified by {@link setDataSourceID}, a databind call will be called by this method.
 277       * @param boolean whether a databind call is required.
 278       */
 279  	protected function setRequiresDataBinding($value)
 280      {
 281          $value=TPropertyValue::ensureBoolean($value);
 282          if($value && $this->_prerendered)
 283          {
 284              $this->_requiresDataBinding=true;
 285              $this->ensureDataBound();
 286          }
 287          else
 288              $this->_requiresDataBinding=$value;
 289      }
 290  
 291      /**
 292       * Ensures any pending {@link dataBind} is called.
 293       * This method calls {@link dataBind} if the data source is specified
 294       * by {@link setDataSourceID} or if {@link getRequiresDataBinding RequiresDataBinding}
 295       * is true.
 296       */
 297  	protected function ensureDataBound()
 298      {
 299          if($this->_requiresDataBinding && ($this->getUsingDataSourceID() || $this->_requiresBindToNull))
 300          {
 301              $this->dataBind();
 302              $this->_requiresBindToNull=false;
 303          }
 304      }
 305  
 306      /**
 307       * @return TPagedDataSource creates a paged data source
 308       */
 309  	protected function createPagedDataSource()
 310      {
 311          $ds=new TPagedDataSource;
 312          $ds->setCurrentPageIndex($this->getCurrentPageIndex());
 313          $ds->setPageSize($this->getPageSize());
 314          $ds->setAllowPaging($this->getAllowPaging());
 315          $ds->setAllowCustomPaging($this->getAllowCustomPaging());
 316          $ds->setVirtualItemCount($this->getVirtualItemCount());
 317          return $ds;
 318      }
 319  
 320      /**
 321       * Performs databinding.
 322       * This method overrides the parent implementation by calling
 323       * {@link performSelect} which fetches data from data source and does
 324       * the actual binding work.
 325       */
 326  	public function dataBind()
 327      {
 328          $this->setRequiresDataBinding(false);
 329          $this->dataBindProperties();
 330          $this->onDataBinding(null);
 331          $data=$this->getData();
 332          if($data instanceof Traversable)
 333          {
 334              if($this->getAllowPaging())
 335              {
 336                  $ds=$this->createPagedDataSource();
 337                  $ds->setDataSource($data);
 338                  $this->setViewState('PageCount',$ds->getPageCount());
 339                  if($ds->getCurrentPageIndex()>=$ds->getPageCount())
 340                  {
 341                      $ds->setCurrentPageIndex($ds->getPageCount()-1);
 342                      $this->setCurrentPageIndex($ds->getCurrentPageIndex());
 343                  }
 344                  $this->performDataBinding($ds);
 345              }
 346              else
 347              {
 348                  $this->clearViewState('PageCount');
 349                  $this->performDataBinding($data);
 350              }
 351          }
 352          $this->setIsDataBound(true);
 353          $this->onDataBound(null);
 354      }
 355  
 356  	public function dataSourceViewChanged($sender,$param)
 357      {
 358          if(!$this->_ignoreDataSourceViewChanged)
 359              $this->setRequiresDataBinding(true);
 360      }
 361  
 362  	protected function getData()
 363      {
 364          if(($view=$this->getDataSourceView())!==null)
 365              return $view->select($this->getSelectParameters());
 366          else
 367              return null;
 368      }
 369  
 370  	protected function getDataSourceView()
 371      {
 372          if(!$this->_currentViewValid)
 373          {
 374              if($this->_currentView && $this->_currentViewIsFromDataSourceID)
 375                  $this->_currentView->detachEventHandler('DataSourceViewChanged',array($this,'dataSourceViewChanged'));
 376              if(($dataSource=$this->determineDataSource())!==null)
 377              {
 378                  if(($view=$dataSource->getView($this->getDataMember()))===null)
 379                      throw new TInvalidDataValueException('databoundcontrol_datamember_invalid',$this->getDataMember());
 380                  if($this->_currentViewIsFromDataSourceID=$this->getUsingDataSourceID())
 381                      $view->attachEventHandler('OnDataSourceViewChanged',array($this,'dataSourceViewChanged'));
 382                  $this->_currentView=$view;
 383              }
 384              else
 385                  $this->_currentView=null;
 386              $this->_currentViewValid=true;
 387          }
 388          return $this->_currentView;
 389      }
 390  
 391  	protected function determineDataSource()
 392      {
 393          if(!$this->_currentDataSourceValid)
 394          {
 395              if(($dsid=$this->getDataSourceID())!=='')
 396              {
 397                  if(($dataSource=$this->getNamingContainer()->findControl($dsid))===null)
 398                      throw new TInvalidDataValueException('databoundcontrol_datasourceid_inexistent',$dsid);
 399                  else if(!($dataSource instanceof IDataSource))
 400                      throw new TInvalidDataValueException('databoundcontrol_datasourceid_invalid',$dsid);
 401                  else
 402                      $this->_currentDataSource=$dataSource;
 403              }
 404              else if(($dataSource=$this->getDataSource())!==null)
 405                  $this->_currentDataSource=new TReadOnlyDataSource($dataSource,$this->getDataMember());
 406              else
 407                  $this->_currentDataSource=null;
 408              $this->_currentDataSourceValid=true;
 409          }
 410          return $this->_currentDataSource;
 411      }
 412  
 413      abstract protected function performDataBinding($data);
 414  
 415      /**
 416       * Raises <b>OnDataBound</b> event.
 417       * This method should be invoked after a databind is performed.
 418       * It is mainly used by framework and component developers.
 419       */
 420  	public function onDataBound($param)
 421      {
 422          $this->raiseEvent('OnDataBound',$this,$param);
 423      }
 424  
 425      /**
 426       * Sets page's <b>OnPreLoad</b> event handler as {@link pagePreLoad}.
 427       * If viewstate is disabled and the current request is a postback,
 428       * {@link setRequiresDataBinding RequiresDataBinding} will be set true.
 429       * This method overrides the parent implementation.
 430       * @param TEventParameter event parameter
 431       */
 432  	public function onInit($param)
 433      {
 434          parent::onInit($param);
 435          $page=$this->getPage();
 436          $page->attachEventHandler('OnPreLoad',array($this,'pagePreLoad'));
 437      }
 438  
 439      /**
 440       * Sets {@link getInitialized} as true.
 441       * This method is invoked when page raises <b>PreLoad</b> event.
 442       * @param mixed event sender
 443       * @param TEventParameter event parameter
 444       */
 445  	public function pagePreLoad($sender,$param)
 446      {
 447          $this->_initialized=true;
 448          $isPostBack=$this->getPage()->getIsPostBack();
 449          if(!$isPostBack || ($isPostBack && (!$this->getEnableViewState(true) || !$this->getIsDataBound())))
 450              $this->setRequiresDataBinding(true);
 451      }
 452  
 453      /**
 454       * Ensures any pending databind is performed.
 455       * This method overrides the parent implementation.
 456       * @param TEventParameter event parameter
 457       */
 458  	public function onPreRender($param)
 459      {
 460          $this->_prerendered=true;
 461          $this->ensureDataBound();
 462          parent::onPreRender($param);
 463      }
 464  
 465      /**
 466       * Validates if the parameter is a valid data source.
 467       * If it is a string or an array, it will be converted as a TList object.
 468       * @param Traversable|array|string data source to be validated
 469       * @return Traversable the data that is traversable
 470       * @throws TInvalidDataTypeException if the data is neither null nor Traversable
 471       */
 472  	protected function validateDataSource($value)
 473      {
 474          if(is_string($value))
 475          {
 476              $list=new TList;
 477              foreach(TPropertyValue::ensureArray($value) as $key=>$value)
 478              {
 479                  if(is_array($value))
 480                      $list->add($value);
 481                  else
 482                      $list->add(array($value,is_string($key)?$key:$value));
 483              }
 484              return $list;
 485          }
 486          else if(is_array($value))
 487              return new TMap($value);
 488          else if(($value instanceof Traversable) || $value===null)
 489              return $value;
 490          else
 491              throw new TInvalidDataTypeException('databoundcontrol_datasource_invalid',get_class($this));
 492      }
 493  
 494  	public function getDataMember()
 495      {
 496          return $this->getViewState('DataMember','');
 497      }
 498  
 499  	public function setDataMember($value)
 500      {
 501          $this->setViewState('DataMember',$value,'');
 502      }
 503  
 504  	public function getSelectParameters()
 505      {
 506          if(!$this->_parameters)
 507              $this->_parameters=new TDataSourceSelectParameters;
 508          return $this->_parameters;
 509      }
 510  }
 511  
 512  
 513  /**
 514   * TListItemType class.
 515   * TListItemType defines the enumerable type for the possible types
 516   * that databound list items could take.
 517   *
 518   * The following enumerable values are defined:
 519   * - Header: header item
 520   * - Footer: footer item
 521   * - Item: content item (neither header nor footer)
 522   * - Separator: separator between items
 523   * - AlternatingItem: alternating content item
 524   * - EditItem: content item in edit mode
 525   * - SelectedItem: selected content item
 526   * - Pager: pager
 527   *
 528   * @author Qiang Xue <qiang.xue@gmail.com>
 529   * @version $Id: TDataBoundControl.php 1533 2006-12-01 12:37:06Z xue $
 530   * @package System.Web.UI.WebControls
 531   * @since 3.0.4
 532   */
 533  class TListItemType extends TEnumerable
 534  {
 535      const Header='Header';
 536      const Footer='Footer';
 537      const Item='Item';
 538      const Separator='Separator';
 539      const AlternatingItem='AlternatingItem';
 540      const EditItem='EditItem';
 541      const SelectedItem='SelectedItem';
 542      const Pager='Pager';
 543  }
 544  
 545  ?>


Généré le : Sun Feb 25 21:07:04 2007 par Balluche grâce à PHPXref 0.7