Blame | Letzte Änderung | Log anzeigen | RSS feed
<?php/*** TPage class file** @author Qiang Xue <qiang.xue@gmail.com>* @link http://www.pradosoft.com/* @copyright Copyright © 2005-2008 PradoSoft* @license http://www.pradosoft.com/license/* @version $Id: TPage.php 2523 2008-10-14 14:05:27Z mikl $* @package System.Web.UI*/Prado::using('System.Web.UI.WebControls.*');Prado::using('System.Web.UI.TControl');Prado::using('System.Web.UI.WebControls.TWebControl');Prado::using('System.Web.UI.TCompositeControl');Prado::using('System.Web.UI.TTemplateControl');Prado::using('System.Web.UI.TForm');Prado::using('System.Web.UI.TClientScriptManager');/*** TPage class** @author Qiang Xue <qiang.xue@gmail.com>* @version $Id: TPage.php 2523 2008-10-14 14:05:27Z mikl $* @package System.Web.UI* @since 3.0*/class TPage extends TTemplateControl{/*** system post fields*/const FIELD_POSTBACK_TARGET='PRADO_POSTBACK_TARGET';const FIELD_POSTBACK_PARAMETER='PRADO_POSTBACK_PARAMETER';const FIELD_LASTFOCUS='PRADO_LASTFOCUS';const FIELD_PAGESTATE='PRADO_PAGESTATE';const FIELD_CALLBACK_TARGET='PRADO_CALLBACK_TARGET';const FIELD_CALLBACK_PARAMETER='PRADO_CALLBACK_PARAMETER';/*** @var array system post fields*/private static $_systemPostFields=array('PRADO_POSTBACK_TARGET'=>true,'PRADO_POSTBACK_PARAMETER'=>true,'PRADO_LASTFOCUS'=>true,'PRADO_PAGESTATE'=>true,'PRADO_CALLBACK_TARGET'=>true,'PRADO_CALLBACK_PARAMETER'=>true);/*** @var TForm form instance*/private $_form;/*** @var THead head instance*/private $_head;/*** @var array list of registered validators*/private $_validators=array();/*** @var boolean if validation has been performed*/private $_validated=false;/*** @var TTheme page theme*/private $_theme;/*** @var string page title set when Head is not in page yet*/private $_title;/*** @var TTheme page stylesheet theme*/private $_styleSheet;/*** @var TClientScriptManager client script manager*/private $_clientScript;/*** @var TMap data post back by user*/private $_postData;/*** @var TMap postback data that is not handled during first invocation of LoadPostData.*/private $_restPostData;/*** @var array list of controls whose data have been changed due to the postback*/private $_controlsPostDataChanged=array();/*** @var array list of controls that need to load post data in the current request*/private $_controlsRequiringPostData=array();/*** @var array list of controls that need to load post data in the next postback*/private $_controlsRegisteredForPostData=array();/*** @var TControl control that needs to raise postback event*/private $_postBackEventTarget;/*** @var string postback event parameter*/private $_postBackEventParameter;/*** @var boolean whether the form has been rendered*/private $_formRendered=false;/*** @var boolean whether the current rendering is within a form*/private $_inFormRender=false;/*** @var TControl|string the control or the ID of the element on the page to be focused when the page is sent back to user*/private $_focus;/*** @var string page path to this page*/private $_pagePath='';/*** @var boolean whether page state should be HMAC validated*/private $_enableStateValidation=true;/*** @var boolean whether page state should be encrypted*/private $_enableStateEncryption=false;/*** @var string page state persister class name*/private $_statePersisterClass='System.Web.UI.TPageStatePersister';/*** @var mixed page state persister*/private $_statePersister;/*** @var TStack stack used to store currently active caching controls*/private $_cachingStack;/*** @var string state string to be stored on the client side*/private $_clientState='';/*** @var array post data loader IDs.*/private $_postDataLoaders=array();/*** @var boolean true if loading post data.*/private $_isLoadingPostData=false;/*** @var boolean whether client supports javascript*/private $_enableJavaScript=true;/*** Constructor.* Sets the page object to itself.* Derived classes must call parent implementation.*/public function __construct(){parent::__construct();$this->setPage($this);}/*** Runs through the page lifecycles.* @param THtmlTextWriter the HTML writer*/public function run($writer){Prado::trace("Running page life cycles",'System.Web.UI.TPage');$this->determinePostBackMode();if($this->getIsPostBack()){if($this->getIsCallback())$this->processCallbackRequest($writer);else$this->processPostBackRequest($writer);}else$this->processNormalRequest($writer);}protected function processNormalRequest($writer){Prado::trace("Page onPreInit()",'System.Web.UI.TPage');$this->onPreInit(null);Prado::trace("Page initRecursive()",'System.Web.UI.TPage');$this->initRecursive();Prado::trace("Page onInitComplete()",'System.Web.UI.TPage');$this->onInitComplete(null);Prado::trace("Page onPreLoad()",'System.Web.UI.TPage');$this->onPreLoad(null);Prado::trace("Page loadRecursive()",'System.Web.UI.TPage');$this->loadRecursive();Prado::trace("Page onLoadComplete()",'System.Web.UI.TPage');$this->onLoadComplete(null);Prado::trace("Page preRenderRecursive()",'System.Web.UI.TPage');$this->preRenderRecursive();Prado::trace("Page onPreRenderComplete()",'System.Web.UI.TPage');$this->onPreRenderComplete(null);Prado::trace("Page savePageState()",'System.Web.UI.TPage');$this->savePageState();Prado::trace("Page onSaveStateComplete()",'System.Web.UI.TPage');$this->onSaveStateComplete(null);Prado::trace("Page renderControl()",'System.Web.UI.TPage');$this->renderControl($writer);Prado::trace("Page unloadRecursive()",'System.Web.UI.TPage');$this->unloadRecursive();}protected function processPostBackRequest($writer){Prado::trace("Page onPreInit()",'System.Web.UI.TPage');$this->onPreInit(null);Prado::trace("Page initRecursive()",'System.Web.UI.TPage');$this->initRecursive();Prado::trace("Page onInitComplete()",'System.Web.UI.TPage');$this->onInitComplete(null);$this->_restPostData=new TMap;Prado::trace("Page loadPageState()",'System.Web.UI.TPage');$this->loadPageState();Prado::trace("Page processPostData()",'System.Web.UI.TPage');$this->processPostData($this->_postData,true);Prado::trace("Page onPreLoad()",'System.Web.UI.TPage');$this->onPreLoad(null);Prado::trace("Page loadRecursive()",'System.Web.UI.TPage');$this->loadRecursive();Prado::trace("Page processPostData()",'System.Web.UI.TPage');$this->processPostData($this->_restPostData,false);Prado::trace("Page raiseChangedEvents()",'System.Web.UI.TPage');$this->raiseChangedEvents();Prado::trace("Page raisePostBackEvent()",'System.Web.UI.TPage');$this->raisePostBackEvent();Prado::trace("Page onLoadComplete()",'System.Web.UI.TPage');$this->onLoadComplete(null);Prado::trace("Page preRenderRecursive()",'System.Web.UI.TPage');$this->preRenderRecursive();Prado::trace("Page onPreRenderComplete()",'System.Web.UI.TPage');$this->onPreRenderComplete(null);Prado::trace("Page savePageState()",'System.Web.UI.TPage');$this->savePageState();Prado::trace("Page onSaveStateComplete()",'System.Web.UI.TPage');$this->onSaveStateComplete(null);Prado::trace("Page renderControl()",'System.Web.UI.TPage');$this->renderControl($writer);Prado::trace("Page unloadRecursive()",'System.Web.UI.TPage');$this->unloadRecursive();}/*** Sets Adapter to TActivePageAdapter and calls apter to process the* callback request.*/protected function processCallbackRequest($writer){Prado::using('System.Web.UI.ActiveControls.TActivePageAdapter');$this->setAdapter(new TActivePageAdapter($this));// Decode Callback postData from UTF-8 to current Charsetif (($g=$this->getApplication()->getGlobalization(false))!==null &&strtoupper($enc=$g->getCharset())!='UTF-8')foreach ($this->_postData as $k=>$v)$this->_postData[$k]=iconv('UTF-8',$enc.'//IGNORE',$v);Prado::trace("Page onPreInit()",'System.Web.UI.TPage');$this->onPreInit(null);Prado::trace("Page initRecursive()",'System.Web.UI.TPage');$this->initRecursive();Prado::trace("Page onInitComplete()",'System.Web.UI.TPage');$this->onInitComplete(null);$this->_restPostData=new TMap;Prado::trace("Page loadPageState()",'System.Web.UI.TPage');$this->loadPageState();Prado::trace("Page processPostData()",'System.Web.UI.TPage');$this->processPostData($this->_postData,true);Prado::trace("Page onPreLoad()",'System.Web.UI.TPage');$this->onPreLoad(null);Prado::trace("Page loadRecursive()",'System.Web.UI.TPage');$this->loadRecursive();Prado::trace("Page processPostData()",'System.Web.UI.TPage');$this->processPostData($this->_restPostData,false);Prado::trace("Page raiseChangedEvents()",'System.Web.UI.TPage');$this->raiseChangedEvents();$this->getAdapter()->processCallbackEvent($writer);/*Prado::trace("Page raisePostBackEvent()",'System.Web.UI.TPage');$this->raisePostBackEvent();*/Prado::trace("Page onLoadComplete()",'System.Web.UI.TPage');$this->onLoadComplete(null);Prado::trace("Page preRenderRecursive()",'System.Web.UI.TPage');$this->preRenderRecursive();Prado::trace("Page onPreRenderComplete()",'System.Web.UI.TPage');$this->onPreRenderComplete(null);Prado::trace("Page savePageState()",'System.Web.UI.TPage');$this->savePageState();Prado::trace("Page onSaveStateComplete()",'System.Web.UI.TPage');$this->onSaveStateComplete(null);/*Prado::trace("Page renderControl()",'System.Web.UI.TPage');$this->renderControl($writer);*/$this->getAdapter()->renderCallbackResponse($writer);Prado::trace("Page unloadRecursive()",'System.Web.UI.TPage');$this->unloadRecursive();}/*** Gets the callback client script handler that allows javascript functions* to be executed during the callback response.* @return TCallbackClientScript interface to client-side javascript code.*/public function getCallbackClient(){if($this->getAdapter() !== null)return $this->getAdapter()->getCallbackClientHandler();elsereturn new TCallbackClientScript();}/*** Set a new callback client handler.* @param TCallbackClientScript new callback client script handler.*/public function setCallbackClient($client){$this->getAdapter()->setCallbackClientHandler($client);}/*** @return TControl the control responsible for the current callback event,* null if nonexistent*/public function getCallbackEventTarget(){return $this->getAdapter()->getCallbackEventTarget();}/*** Registers a control to raise callback event in the current request.* @param TControl control registered to raise callback event.*/public function setCallbackEventTarget(TControl $control){$this->getAdapter()->setCallbackEventTarget($control);}/*** Callback parameter is decoded assuming JSON encoding.* @return string callback event parameter*/public function getCallbackEventParameter(){return $this->getAdapter()->getCallbackEventParameter();}/*** @param mixed callback event parameter*/public function setCallbackEventParameter($value){$this->getAdapter()->setCallbackEventParameter($value);}/*** Register post data loaders for Callback to collect post data.* This method should only be called by framework developers.* @param TControl control that requires post data.* @see TControl::preRenderRecursive();*/public function registerPostDataLoader($control){$id=is_string($control)?$control:$control->getUniqueID();$this->_postDataLoaders[$id] = true;}/*** Get a list of IDs of controls that are enabled and require post data.* @return array list of IDs implementing IPostBackDataHandler*/public function getPostDataLoaders(){return array_keys($this->_postDataLoaders);}/*** @return TForm the form on the page*/public function getForm(){return $this->_form;}/*** Registers a TForm instance to the page.* Note, a page can contain at most one TForm instance.* @param TForm the form on the page* @throws TInvalidOperationException if this method is invoked twice or more.*/public function setForm(TForm $form){if($this->_form===null)$this->_form=$form;elsethrow new TInvalidOperationException('page_form_duplicated');}/*** Returns a list of registered validators.* If validation group is specified, only the validators in that group will be returned.* @param string validation group* @return TList registered validators in the requested group. If the group is null, all validators will be returned.*/public function getValidators($validationGroup=null){if(!$this->_validators)$this->_validators=new TList;if($validationGroup===null)return $this->_validators;else{$list=new TList;foreach($this->_validators as $validator)if($validator->getValidationGroup()===$validationGroup)$list->add($validator);return $list;}}/*** Performs input validation.* This method will invoke the registered validators to perform the actual validation.* If validation group is specified, only the validators in that group will be invoked.* @param string validation group. If null, all validators will perform validation.*/public function validate($validationGroup=null){Prado::trace("Page validate()",'System.Web.UI.TPage');$this->_validated=true;if($this->_validators && $this->_validators->getCount()){if($validationGroup===null){foreach($this->_validators as $validator)$validator->validate();}else{foreach($this->_validators as $validator){if($validator->getValidationGroup()===$validationGroup)$validator->validate();}}}}/*** Returns whether user input is valid or not.* This method must be invoked after {@link validate} is called.* @return boolean whether the user input is valid or not.* @throws TInvalidOperationException if {@link validate} is not invoked yet.*/public function getIsValid(){if($this->_validated){if($this->_validators && $this->_validators->getCount()){foreach($this->_validators as $validator)if(!$validator->getIsValid())return false;}return true;}elsethrow new TInvalidOperationException('page_isvalid_unknown');}/*** @return TTheme the theme used for the page. Defaults to null.*/public function getTheme(){if(is_string($this->_theme))$this->_theme=$this->getService()->getThemeManager()->getTheme($this->_theme);return $this->_theme;}/*** Sets the theme to be used for the page.* @param string|TTheme the theme name or the theme object to be used for the page.*/public function setTheme($value){$this->_theme=empty($value)?null:$value;}/*** @return TTheme the stylesheet theme used for the page. Defaults to null.*/public function getStyleSheetTheme(){if(is_string($this->_styleSheet))$this->_styleSheet=$this->getService()->getThemeManager()->getTheme($this->_styleSheet);return $this->_styleSheet;}/*** Sets the stylesheet theme to be used for the page.* @param string|TTheme the stylesheet theme name or the stylesheet theme object to be used for the page.*/public function setStyleSheetTheme($value){$this->_styleSheet=empty($value)?null:$value;}/*** Applies a skin in the current theme to a control.* This method should only be used by framework developers.* @param TControl a control to be applied skin with*/public function applyControlSkin($control){if(($theme=$this->getTheme())!==null)$theme->applySkin($control);}/*** Applies a stylesheet skin in the current theme to a control.* This method should only be used by framework developers.* @param TControl a control to be applied stylesheet skin with*/public function applyControlStyleSheet($control){if(($theme=$this->getStyleSheetTheme())!==null)$theme->applySkin($control);}/*** @return TClientScriptManager client script manager*/public function getClientScript(){if(!$this->_clientScript)$this->_clientScript=new TClientScriptManager($this);return $this->_clientScript;}/*** Raises OnPreInit event.* This method is invoked right before {@link onInit OnInit} stage.* You may override this method to provide additional initialization that* should be done before {@link onInit OnInit} (e.g. setting {@link setTheme Theme} or* {@link setStyleSheetTheme StyleSheetTheme}).* Remember to call the parent implementation to ensure OnPreInit event is raised.* @param mixed event parameter*/public function onPreInit($param){$this->raiseEvent('OnPreInit',$this,$param);}/*** Raises OnInitComplete event.* This method is invoked right after {@link onInit OnInit} stage and before {@link onLoad OnLoad} stage.* You may override this method to provide additional initialization that* should be done after {@link onInit OnInit}.* Remember to call the parent implementation to ensure OnInitComplete event is raised.* @param mixed event parameter*/public function onInitComplete($param){$this->raiseEvent('OnInitComplete',$this,$param);}/*** Raises OnPreLoad event.* This method is invoked right before {@link onLoad OnLoad} stage.* You may override this method to provide additional page loading logic that* should be done before {@link onLoad OnLoad}.* Remember to call the parent implementation to ensure OnPreLoad event is raised.* @param mixed event parameter*/public function onPreLoad($param){$this->raiseEvent('OnPreLoad',$this,$param);}/*** Raises OnLoadComplete event.* This method is invoked right after {@link onLoad OnLoad} stage.* You may override this method to provide additional page loading logic that* should be done after {@link onLoad OnLoad}.* Remember to call the parent implementation to ensure OnLoadComplete event is raised.* @param mixed event parameter*/public function onLoadComplete($param){$this->raiseEvent('OnLoadComplete',$this,$param);}/*** Raises OnPreRenderComplete event.* This method is invoked right after {@link onPreRender OnPreRender} stage.* You may override this method to provide additional preparation for page rendering* that should be done after {@link onPreRender OnPreRender}.* Remember to call the parent implementation to ensure OnPreRenderComplete event is raised.* @param mixed event parameter*/public function onPreRenderComplete($param){$this->raiseEvent('OnPreRenderComplete',$this,$param);$cs=$this->getClientScript();$theme=$this->getTheme();if($theme instanceof ITheme){foreach($theme->getStyleSheetFiles() as $url)$cs->registerStyleSheetFile($url,$url,$this->getCssMediaType($url));foreach($theme->getJavaScriptFiles() as $url)$cs->registerHeadScriptFile($url,$url);}$styleSheet=$this->getStyleSheetTheme();if($styleSheet instanceof ITheme){foreach($styleSheet->getStyleSheetFiles() as $url)$cs->registerStyleSheetFile($url,$url,$this->getCssMediaType($url));foreach($styleSheet->getJavaScriptFiles() as $url)$cs->registerHeadScriptFile($url,$url);}if($cs->getRequiresHead() && $this->getHead()===null)throw new TConfigurationException('page_head_required');}/*** Determines the media type of the CSS file.* The media type is determined according to the following file name pattern:* xxx.media-type.extension* For example, 'mystyle.print.css' means its media type is 'print'.* @param string CSS URL* @return string media type of the CSS file*/private function getCssMediaType($url){$segs=explode('.',basename($url));if(isset($segs[2]))return $segs[count($segs)-2];elsereturn '';}/*** Raises OnSaveStateComplete event.* This method is invoked right after {@link onSaveState OnSaveState} stage.* You may override this method to provide additional logic after page state is saved.* Remember to call the parent implementation to ensure OnSaveStateComplete event is raised.* @param mixed event parameter*/public function onSaveStateComplete($param){$this->raiseEvent('OnSaveStateComplete',$this,$param);}/*** Determines whether the current page request is a postback.* Call {@link getIsPostBack} to get the result.*/private function determinePostBackMode(){$postData=$this->getRequest();if($postData->contains(self::FIELD_PAGESTATE) || $postData->contains(self::FIELD_POSTBACK_TARGET))$this->_postData=$postData;}/*** @return boolean whether the current page request is a postback*/public function getIsPostBack(){return $this->_postData!==null;}/*** @return boolean whether this is a callback request*/public function getIsCallback(){return $this->getIsPostBack() && $this->getRequest()->contains(self::FIELD_CALLBACK_TARGET);}/*** This method is invoked when control state is to be saved.* You can override this method to do last step state saving.* Parent implementation must be invoked.*/public function saveState(){parent::saveState();$this->setViewState('ControlsRequiringPostBack',$this->_controlsRegisteredForPostData,array());}/*** This method is invoked right after the control has loaded its state.* You can override this method to initialize data from the control state.* Parent implementation must be invoked.*/public function loadState(){parent::loadState();$this->_controlsRequiringPostData=$this->getViewState('ControlsRequiringPostBack',array());}/*** Loads page state from persistent storage.*/protected function loadPageState(){Prado::trace("Loading state",'System.Web.UI.TPage');$state=$this->getStatePersister()->load();$this->loadStateRecursive($state,$this->getEnableViewState());}/*** Saves page state from persistent storage.*/protected function savePageState(){Prado::trace("Saving state",'System.Web.UI.TPage');$state=&$this->saveStateRecursive($this->getEnableViewState());$this->getStatePersister()->save($state);}/*** @param string the field name* @return boolean whether the specified field is a system field in postback data*/protected function isSystemPostField($field){return isset(self::$_systemPostFields[$field]);}/*** Registers a control for loading post data in the next postback.* This method needs to be invoked if the control to load post data* may not have a post variable in some cases. For example, a checkbox,* if not checked, will not have a post value.* @param TControl control registered for loading post data*/public function registerRequiresPostData($control){$id=is_string($control)?$control:$control->getUniqueID();$this->_controlsRegisteredForPostData[$id]=true;$this->registerPostDataLoader($id);$params=func_get_args();foreach($this->getCachingStack() as $item)$item->registerAction('Page','registerRequiresPostData',$id);}/*** @return TControl the control responsible for the current postback event, null if nonexistent*/public function getPostBackEventTarget(){if($this->_postBackEventTarget===null && $this->_postData!==null){$eventTarget=$this->_postData->itemAt(self::FIELD_POSTBACK_TARGET);if(!empty($eventTarget))$this->_postBackEventTarget=$this->findControl($eventTarget);}return $this->_postBackEventTarget;}/*** Registers a control to raise postback event in the current request.* @param TControl control registered to raise postback event.*/public function setPostBackEventTarget(TControl $control){$this->_postBackEventTarget=$control;}/*** @return string postback event parameter*/public function getPostBackEventParameter(){if($this->_postBackEventParameter===null && $this->_postData!==null){if(($this->_postBackEventParameter=$this->_postData->itemAt(self::FIELD_POSTBACK_PARAMETER))===null)$this->_postBackEventParameter='';}return $this->_postBackEventParameter;}/*** @param string postback event parameter*/public function setPostBackEventParameter($value){$this->_postBackEventParameter=$value;}/*** Processes post data.* @param TMap post data to be processed* @param boolean whether this method is invoked before {@link onLoad OnLoad}.*/protected function processPostData($postData,$beforeLoad){$this->_isLoadingPostData=true;if($beforeLoad)$this->_restPostData=new TMap;foreach($postData as $key=>$value){if($this->isSystemPostField($key))continue;else if($control=$this->findControl($key)){if($control instanceof IPostBackDataHandler){if($control->loadPostData($key,$postData))$this->_controlsPostDataChanged[]=$control;}else if($control instanceof IPostBackEventHandler &&empty($this->_postData[self::FIELD_POSTBACK_TARGET])){$this->_postData->add(self::FIELD_POSTBACK_TARGET,$key); // not calling setPostBackEventTarget() because the control may be removed later}unset($this->_controlsRequiringPostData[$key]);}else if($beforeLoad)$this->_restPostData->add($key,$value);}foreach($this->_controlsRequiringPostData as $key=>$value){if($control=$this->findControl($key)){if($control instanceof IPostBackDataHandler){if($control->loadPostData($key,$this->_postData))$this->_controlsPostDataChanged[]=$control;}elsethrow new TInvalidDataValueException('page_postbackcontrol_invalid',$key);unset($this->_controlsRequiringPostData[$key]);}}$this->_isLoadingPostData=false;}/*** @return boolean true if loading post data.*/public function getIsLoadingPostData(){return $this->_isLoadingPostData;}/*** Raises OnPostDataChangedEvent for controls whose data have been changed due to the postback.*/private function raiseChangedEvents(){foreach($this->_controlsPostDataChanged as $control)$control->raisePostDataChangedEvent();}/*** Raises PostBack event.*/private function raisePostBackEvent(){if(($postBackHandler=$this->getPostBackEventTarget())===null)$this->validate();else if($postBackHandler instanceof IPostBackEventHandler)$postBackHandler->raisePostBackEvent($this->getPostBackEventParameter());}/*** Ensures the control is rendered within a form.* @param TControl the control to be rendered* @throws TConfigurationException if the control is outside of the form*/public function ensureRenderInForm($control){if(!$this->getIsCallback() && !$this->_inFormRender)throw new TConfigurationException('page_control_outofform',get_class($control),$control->getUniqueID());}/*** @internal This method is invoked by TForm at the beginning of its rendering*/public function beginFormRender($writer){if($this->_formRendered)throw new TConfigurationException('page_form_duplicated');$this->_formRendered=true;$this->_inFormRender=true;$this->getClientScript()->registerHiddenField(self::FIELD_PAGESTATE,$this->getClientState());}/*** @internal This method is invoked by TForm at the end of its rendering*/public function endFormRender($writer){if($this->_focus){if(($this->_focus instanceof TControl) && $this->_focus->getVisible(true))$focus=$this->_focus->getClientID();else$focus=$this->_focus;$this->getClientScript()->registerFocusControl($focus);}else if($this->_postData && ($lastFocus=$this->_postData->itemAt(self::FIELD_LASTFOCUS))!==null)$this->getClientScript()->registerFocusControl($lastFocus);$this->_inFormRender=false;}/*** Sets input focus on a control after the page is rendered to users.* @param TControl|string control to receive focus, or the ID of the element on the page to receive focus*/public function setFocus($value){$this->_focus=$value;}/*** @return boolean whether client supports javascript. Defaults to true.*/public function getClientSupportsJavaScript(){return $this->_enableJavaScript;}/*** @param boolean whether client supports javascript. If false, javascript will not be generated for controls.*/public function setClientSupportsJavaScript($value){$this->_enableJavaScript=TPropertyValue::ensureBoolean($value);}/*** @return THead page head, null if not available*/public function getHead(){return $this->_head;}/*** @param THead page head* @throws TInvalidOperationException if a head already exists*/public function setHead(THead $value){if($this->_head)throw new TInvalidOperationException('page_head_duplicated');$this->_head=$value;if($this->_title!==null){$this->_head->setTitle($this->_title);$this->_title=null;}}/*** @return string page title.*/public function getTitle(){if($this->_head)return $this->_head->getTitle();elsereturn $this->_title===null ? '' : $this->_title;}/*** Sets the page title.* Note, a {@link THead} control needs to place on the page* in order that this title be rendered.* @param string page title. This will override the title set in {@link getHead Head}.*/public function setTitle($value){if($this->_head)$this->_head->setTitle($value);else$this->_title=$value;}/*** Returns the state to be stored on the client side.* This method should only be used by framework and control developers.* @return string the state to be stored on the client side*/public function getClientState(){return $this->_clientState;}/*** Sets the state to be stored on the client side.* This method should only be used by framework and control developers.* @param string the state to be stored on the client side*/public function setClientState($state){$this->_clientState=$state;}/*** @return string the state postback from client side*/public function getRequestClientState(){return $this->getRequest()->itemAt(self::FIELD_PAGESTATE);}/*** @return string class name of the page state persister. Defaults to TPageStatePersister.*/public function getStatePersisterClass(){return $this->_statePersisterClass;}/*** @param string class name of the page state persister.*/public function setStatePersisterClass($value){$this->_statePersisterClass=$value;}/*** @return IPageStatePersister page state persister*/public function getStatePersister(){if($this->_statePersister===null){$this->_statePersister=Prado::createComponent($this->_statePersisterClass);if(!($this->_statePersister instanceof IPageStatePersister))throw new TInvalidDataTypeException('page_statepersister_invalid');$this->_statePersister->setPage($this);}return $this->_statePersister;}/*** @return boolean whether page state should be HMAC validated. Defaults to true.*/public function getEnableStateValidation(){return $this->_enableStateValidation;}/*** @param boolean whether page state should be HMAC validated.*/public function setEnableStateValidation($value){$this->_enableStateValidation=TPropertyValue::ensureBoolean($value);}/*** @return boolean whether page state should be encrypted. Defaults to false.*/public function getEnableStateEncryption(){return $this->_enableStateEncryption;}/*** @param boolean whether page state should be encrypted.*/public function setEnableStateEncryption($value){$this->_enableStateEncryption=TPropertyValue::ensureBoolean($value);}/*** @return string the requested page path for this page*/public function getPagePath(){return $this->_pagePath;}/*** @param string the requested page path for this page*/public function setPagePath($value){$this->_pagePath=$value;}/*** Registers an action associated with the content being cached.* The registered action will be replayed if the content stored* in the cache is served to end-users.* @param string context of the action method. This is a property-path* referring to the context object (e.g. Page, Page.ClientScript).* @param string method name of the context object* @param array list of parameters to be passed to the action method*/public function registerCachingAction($context,$funcName,$funcParams){if($this->_cachingStack){foreach($this->_cachingStack as $cache)$cache->registerAction($context,$funcName,$funcParams);}}/*** @return TStack stack of {@link TOutputCache} objects*/public function getCachingStack(){if(!$this->_cachingStack)$this->_cachingStack=new TStack;return $this->_cachingStack;}}/*** IPageStatePersister interface.** IPageStatePersister interface is required for all page state persister* classes.** @author Qiang Xue <qiang.xue@gmail.com>* @version $Id: TPage.php 2523 2008-10-14 14:05:27Z mikl $* @package System.Web.UI* @since 3.1*/interface IPageStatePersister{/*** @param TPage the page that this persister works for*/public function getPage();/*** @param TPage the page that this persister works for*/public function setPage(TPage $page);/*** Saves state to persistent storage.* @param mixed state to be stored*/public function save($state);/*** Loads page state from persistent storage* @return mixed the restored state*/public function load();}/*** TPageStateFormatter class.** TPageStateFormatter is a utility class to transform the page state* into and from a string that can be properly saved in persistent storage.** Depending on the {@link TPage::getEnableStateValidation() EnableStateValidation}* and {@link TPage::getEnableStateEncryption() EnableStateEncryption},* TPageStateFormatter may do HMAC validation and encryption to prevent* the state data from being tampered or viewed.* The private keys and hashing/encryption methods are determined by* {@link TApplication::getSecurityManager() SecurityManager}.** @author Qiang Xue <qiang.xue@gmail.com>* @version $Revision: $ $Date: $* @package System.Web.UI* @since 3.1*/class TPageStateFormatter{/*** @param TPage* @param mixed state data* @return string serialized data*/public static function serialize($page,$data){$sm=$page->getApplication()->getSecurityManager();if($page->getEnableStateValidation())$str=$sm->hashData(Prado::serialize($data));else$str=Prado::serialize($data);if(extension_loaded('zlib'))$str=gzcompress($str);if($page->getEnableStateEncryption())$str=$sm->encrypt($str);return base64_encode($str);}/*** @param TPage* @param string serialized data* @return mixed unserialized state data, null if data is corrupted*/public static function unserialize($page,$data){$str=base64_decode($data);if($str==='')return null;if($str!==false){$sm=$page->getApplication()->getSecurityManager();if($page->getEnableStateEncryption())$str=$sm->decrypt($str);if(extension_loaded('zlib'))$str=@gzuncompress($str);if($page->getEnableStateValidation()){if(($str=$sm->validateData($str))!==false)return Prado::unserialize($str);}elsereturn $str;}return null;}}?>