| [ Index ] |
|
Code source de PRADO 3.0.6 |
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 © 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 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
| Généré le : Sun Feb 25 21:07:04 2007 | par Balluche grâce à PHPXref 0.7 |