_dataSource; } /** * @param Traversable|array|string data source object */ public function setDataSource($value) { if($value!==null) $this->validateDataSource($value); $this->_dataSource=$value; $this->onDataPropertyChanged(); } /** * @return string ID path to the data source control. Defaults to empty. */ public function getDataSourceID() { return $this->getViewState('DataSourceID',''); } /** * @param string ID path to the data source control. The data source * control must be locatable via {@link TControl::findControl} call. */ public function setDataSourceID($value) { $dsid=$this->getViewState('DataSourceID',''); if($dsid!=='' && $value==='') $this->_requiresBindToNull=true; $this->setViewState('DataSourceID',$value,''); $this->onDataPropertyChanged(); } /** * This method is invoked when either {@link setDataSource} or {@link setDataSourceID} is changed. */ protected function onDataPropertyChanged() { if($this->_throwOnDataPropertyChanged) throw new TInvalidOperationException('databoundcontrol_dataproperty_unchangeable'); if($this->getInitialized()) $this->setRequiresDataBinding(true); } /** * @return boolean whether the databound control has been initialized. */ protected function getInitialized() { return $this->_initialized; } /** * @param boolean a value indicating whether the databound control is initialized. */ protected function setInitialized($value) { $this->_initialized=TPropertyValue::ensureBoolean($value); } /** * @return boolean if the databound control uses the data source control specified * by {@link setDataSourceID}, or it uses the data source object specified * by {@link setDataSource}. */ protected function getUsingDataSourceID() { return $this->getDataSourceID()!==''; } /** * @return boolean whether a databind call is required (by the data bound control) */ protected function getRequiresDataBinding() { return $this->_requiresDataBinding; } /** * Sets a value indicating whether a databind call is required by the data bound control. * If true and the control has been prerendered while it uses the data source * specified by {@link setDataSourceID}, a databind call will be called by this method. * @param boolean whether a databind call is required. */ protected function setRequiresDataBinding($value) { $value=TPropertyValue::ensureBoolean($value); if($value && $this->_prerendered && $this->getUsingDataSourceID()) { $this->_requiresDataBinding=true; $this->ensureDataBound(); } else $this->_requiresDataBinding=$value; } /** * Performs databinding. * This method overrides the parent implementation by calling * {@link performSelect} which fetches data from data source and does * the actual binding work. * @param boolean whether to raise DataBind event. This parameter is ignored. */ public function dataBind($raiseDataBindingEvent=true) { $this->performSelect(); } /** * Ensures any pending {@link dataBind} is called. * This method calls {@link dataBind} if the data source is specified * by {@link setDataSourceID} or if {@link getRequiresDataBinding RequiresDataBinding} * is true. */ protected function ensureDataBound() { try { $this->_throwOnDataPropertyChange=true; if($this->_requiresDataBinding && ($this->getUsingDataSourceID() || $this->_requiresBindToNull)) { $this->dataBind(); $this->_requiresBindToNull=false; } } catch(Exception $e) { $this->_throwOnDataPropertyChange=false; throw $e; } } /** * Raises DataBound event. * This method should be invoked after a databind is performed. * It is mainly used by framework and component developers. */ public function onDataBound($param) { $this->raiseEvent('DataBound',$this,$param); } /** * Sets page's PreLoad event handler as {@link onPagePreLoad}. * If viewstate is disabled and the current request is a postback, * {@link setRequiresDataBinding RequiresDataBinding} will be set true. * This method overrides the parent implementation. * @param TEventParameter event parameter */ protected function onInit($param) { parent::onInit($param); $page=$this->getPage(); $page->attachEventHandler('PreLoad',array($this,'onPagePreLoad')); if(!$this->getEnableViewState(true) && $page->getIsPostBack()) $this->setRequiresDataBinding(true); } /** * Sets {@link getInitialized} as true. * This method is invoked when page raises PreLoad event. * @param mixed event sender * @param TEventParameter event parameter */ protected function onPagePreLoad($sender,$param) { $this->_initialized=true; } /** * Ensures any pending databind is performed. * This method overrides the parent implementation. * @param TEventParameter event parameter */ protected function onPreRender($param) { $this->_prerendered=true; $this->ensureDataBound(); parent::onPreRender($param); } /** * Validates if the parameter is a valid data source. * @return boolean if the parameter is a valid data source */ protected function validateDataSource($value) { if(!is_array($value) && !($value instanceof Traversable)) throw new TInvalidDataTypeException('databoundcontrol_datasource_invalid'); } /** * @return ??? */ protected function performSelect() { if(!$this->getUsingDataSourceID()) $this->onDataBinding(null); $view=$this->getDataSourceView(); $this->setRequiresDataBinding(false); $this->setDataBound(true); $data=$view->select($this->getSelectParameters()); if($this->getUsingDataSourceID()) $this->onDataBinding(null); $this->performDataBinding($data); $this->onDataBound(null); } protected function getDataSourceView() { $source=$this->getDataSourceByID(); return $source->getView($this->getDataMember()); } protected function performDataBinding($data) { } public function getDataMember() { return $this->getViewState('DataMember',''); } public function setDataMember($value) { $this->setViewState('DataMember',$value,''); } public function getSelectParameters() { if(!$this->_parameters) $this->_parameters=$this->createSelectParameters(); return $this->_parameters; } protected function createSelectParameters() { return new TDataSourceSelectParameters; } } ?>