From ccf0cd0f8d6480238db531f46ae1c70554d0e90d Mon Sep 17 00:00:00 2001 From: xue <> Date: Sat, 8 Apr 2006 17:00:05 +0000 Subject: Added TOutputCache. --- framework/TApplication.php | 1 + framework/Web/UI/TClientScriptManager.php | 95 +++++++++++---- framework/Web/UI/TControl.php | 12 +- framework/Web/UI/TForm.php | 2 +- framework/Web/UI/TPage.php | 26 ++++- framework/Web/UI/WebControls/TOutputCache.php | 160 ++++++++++++++++++++++++++ framework/Web/UI/WebControls/TPanel.php | 2 +- framework/Web/UI/WebControls/TWizard.php | 1 - 8 files changed, 263 insertions(+), 36 deletions(-) create mode 100644 framework/Web/UI/WebControls/TOutputCache.php (limited to 'framework') diff --git a/framework/TApplication.php b/framework/TApplication.php index fcc77b16..893856de 100644 --- a/framework/TApplication.php +++ b/framework/TApplication.php @@ -26,6 +26,7 @@ require_once(PRADO_DIR.'/Caching/TCache.php'); require_once(PRADO_DIR.'/IO/TTextWriter.php'); require_once(PRADO_DIR.'/Collections/TList.php'); require_once(PRADO_DIR.'/Collections/TMap.php'); +require_once(PRADO_DIR.'/Collections/TStack.php'); require_once(PRADO_DIR.'/Xml/TXmlDocument.php'); require_once(PRADO_DIR.'/Security/TAuthorizationRule.php'); require_once(PRADO_DIR.'/Security/TSecurityManager.php'); diff --git a/framework/Web/UI/TClientScriptManager.php b/framework/Web/UI/TClientScriptManager.php index 015ef1c1..34f17bf3 100644 --- a/framework/Web/UI/TClientScriptManager.php +++ b/framework/Web/UI/TClientScriptManager.php @@ -115,6 +115,15 @@ class TClientScriptManager extends TApplicationComponent * @param string script library name. */ public function registerPradoScript($name) + { + $this->registerPradoScriptInternal($name); + + $params=func_get_args(); + foreach($this->_page->getCachingStack() as $item) + $item->registerAction('registerPradoScript',$params); + } + + private function registerPradoScriptInternal($name) { if(!isset($this->_registeredPradoScripts[$name])) { @@ -166,47 +175,59 @@ class TClientScriptManager extends TApplicationComponent $options['FormID']=$this->_page->getForm()->getClientID(); $optionString=TJavaScript::encode($options); $code="new $jsClass($optionString);"; - $this->registerEndScript(sprintf('%08X', crc32($code)), $code); - $this->registerHiddenField(TPage::FIELD_POSTBACK_TARGET,''); - $this->registerHiddenField(TPage::FIELD_POSTBACK_PARAMETER,''); + $this->_endScripts[sprintf('%08X', crc32($code))]=$code; + $this->_hiddenFields[TPage::FIELD_POSTBACK_TARGET]=''; + $this->_hiddenFields[TPage::FIELD_POSTBACK_PARAMETER]=''; + $this->registerPradoScriptInternal('prado'); - $this->registerPradoScript('prado'); + $params=func_get_args(); + foreach($this->_page->getCachingStack() as $item) + $item->registerAction('registerPostBackControl',$params); } /** * Register a default button to panel. When the $panel is in focus and * the 'enter' key is pressed, the $button will be clicked. - * @param TControl panel to register the default button action - * @param TControl button to trigger a postback + * @param string client ID of the container object + * @param string client ID of the button */ - public function registerDefaultButton($panel, $button) + public function registerDefaultButton($containerID, $buttonID) { - $options = TJavaScript::encode($this->getDefaultButtonOptions($panel, $button)); + $options = TJavaScript::encode($this->getDefaultButtonOptions($containerID, $buttonID)); $code = "new Prado.WebUI.DefaultButton($options);"; - $this->registerEndScript("prado:".$panel->getClientID(), $code); - $this->registerPradoScript('prado'); + + $this->_endScripts['prado:'.$containerID]=$code; + $this->registerPradoScriptInternal('prado'); + + $params=func_get_args(); + foreach($this->_page->getCachingStack() as $item) + $item->registerAction('registerDefaultButton',$params); } /** * Registers the control to receive default focus. - * @param TControl|string the control or the client ID of the HTML element to receive default focus + * @param string the client ID of the control to receive default focus */ public function registerFocusControl($target) { - $this->registerPradoScript('prado'); - if($target instanceof TControl) - $target=$target->getClientID(); - $this->registerEndScript('prado:focus','Prado.Focus.setFocus("'.TJavaScript::quoteString($target).'");'); + $this->registerPradoScriptInternal('prado'); + $this->_endScripts['prado:focus']='Prado.Focus.setFocus("'.TJavaScript::quoteString($target).'");'; + + $params=func_get_args(); + foreach($this->_page->getCachingStack() as $item) + $item->registerAction('registerFocusControl',$params); } /** + * @param string client ID of the container object + * @param string client ID of the button * @return array default button options. */ - protected function getDefaultButtonOptions($panel, $button) + protected function getDefaultButtonOptions($containerID, $buttonID) { - $options['Panel'] = $panel->getClientID(); - $options['Target'] = $button->getClientID(); + $options['Panel'] = $containerID; + $options['Target'] = $buttonID; $options['Event'] = 'click'; return $options; } @@ -219,6 +240,10 @@ class TClientScriptManager extends TApplicationComponent public function registerStyleSheetFile($key,$url) { $this->_styleSheetFiles[$key]=$url; + + $params=func_get_args(); + foreach($this->_page->getCachingStack() as $item) + $item->registerAction('registerStyleSheetFile',$params); } /** @@ -229,6 +254,10 @@ class TClientScriptManager extends TApplicationComponent public function registerStyleSheet($key,$css) { $this->_styleSheets[$key]=$css; + + $params=func_get_args(); + foreach($this->_page->getCachingStack() as $item) + $item->registerAction('registerStyleSheet',$params); } /** @@ -239,6 +268,10 @@ class TClientScriptManager extends TApplicationComponent public function registerHeadScriptFile($key,$url) { $this->_headScriptFiles[$key]=$url; + + $params=func_get_args(); + foreach($this->_page->getCachingStack() as $item) + $item->registerAction('registerHeadScriptFile',$params); } /** @@ -249,6 +282,10 @@ class TClientScriptManager extends TApplicationComponent public function registerHeadScript($key,$script) { $this->_headScripts[$key]=$script; + + $params=func_get_args(); + foreach($this->_page->getCachingStack() as $item) + $item->registerAction('registerHeadScript',$params); } /** @@ -258,8 +295,11 @@ class TClientScriptManager extends TApplicationComponent */ public function registerScriptFile($key,$url) { - if(!isset($this->_scriptFiles[$key])) - $this->_scriptFiles[$key]=$url; + $this->_scriptFiles[$key]=$url; + + $params=func_get_args(); + foreach($this->_page->getCachingStack() as $item) + $item->registerAction('registerScriptFile',$params); } /** @@ -270,6 +310,10 @@ class TClientScriptManager extends TApplicationComponent public function registerBeginScript($key,$script) { $this->_beginScripts[$key]=$script; + + $params=func_get_args(); + foreach($this->_page->getCachingStack() as $item) + $item->registerAction('registerBeginScript',$params); } /** @@ -280,6 +324,10 @@ class TClientScriptManager extends TApplicationComponent public function registerEndScript($key,$script) { $this->_endScripts[$key]=$script; + + $params=func_get_args(); + foreach($this->_page->getCachingStack() as $item) + $item->registerAction('registerEndScript',$params); } /** @@ -290,8 +338,11 @@ class TClientScriptManager extends TApplicationComponent */ public function registerHiddenField($name,$value) { - if(!isset($this->_hiddenFields[$name])) - $this->_hiddenFields[$name]=$value; + $this->_hiddenFields[$name]=$value; + + $params=func_get_args(); + foreach($this->_page->getCachingStack() as $item) + $item->registerAction('registerHiddenField',$params); } /** diff --git a/framework/Web/UI/TControl.php b/framework/Web/UI/TControl.php index 15965a74..3c3c7060 100644 --- a/framework/Web/UI/TControl.php +++ b/framework/Web/UI/TControl.php @@ -1449,7 +1449,7 @@ class TControl extends TApplicationComponent implements IRenderable, IBindable * @param TMap the collection of the state * @param boolean whether the viewstate should be loaded */ - final protected function loadStateRecursive(&$state,$needViewState=true) + protected function loadStateRecursive(&$state,$needViewState=true) { if($state!==null) { @@ -1492,12 +1492,10 @@ class TControl extends TApplicationComponent implements IRenderable, IBindable } if(!empty($state)) $this->_rf[self::RF_CHILD_STATE]=&$state; - $this->_stage=self::CS_STATE_LOADED; } - else - $this->_stage=self::CS_STATE_LOADED; + $this->_stage=self::CS_STATE_LOADED; if(isset($this->_rf[self::RF_ADAPTER])) - $this->_rf[self::RF_ADAPTER]->loadState(null); + $this->_rf[self::RF_ADAPTER]->loadState(); else $this->loadState(); } @@ -1507,10 +1505,10 @@ class TControl extends TApplicationComponent implements IRenderable, IBindable * @param boolean whether the viewstate should be saved * @return array the collection of the control state (including its children's state). */ - final protected function &saveStateRecursive($needViewState=true) + protected function &saveStateRecursive($needViewState=true) { if(isset($this->_rf[self::RF_ADAPTER])) - $this->_rf[self::RF_ADAPTER]->saveState(null); + $this->_rf[self::RF_ADAPTER]->saveState(); else $this->saveState(); $needViewState=($needViewState && !($this->_flags & self::IS_DISABLE_VIEWSTATE)); diff --git a/framework/Web/UI/TForm.php b/framework/Web/UI/TForm.php index 317b0158..948dea3e 100644 --- a/framework/Web/UI/TForm.php +++ b/framework/Web/UI/TForm.php @@ -58,7 +58,7 @@ class TForm extends TControl if(($butt=$this->getDefaultButton())!=='') { if(($button=$this->findControl($butt))!==null) - $this->getPage()->getClientScript()->registerDefaultButton($this,$button); + $this->getPage()->getClientScript()->registerDefaultButton($this->getClientID(),$button->getClientID()); else throw new TInvalidDataValueException('form_defaultbutton_invalid',$butt); } diff --git a/framework/Web/UI/TPage.php b/framework/Web/UI/TPage.php index b68c4996..7f4c490c 100644 --- a/framework/Web/UI/TPage.php +++ b/framework/Web/UI/TPage.php @@ -141,6 +141,10 @@ class TPage extends TTemplateControl * @var mixed page state persister */ private $_statePersister=null; + /** + * @var TStack stack used to store currently active caching controls + */ + private $_cachingStack=null; /** * Constructor. @@ -599,9 +603,13 @@ class TPage extends TTemplateControl * if not checked, will not have a post value. * @param TControl control registered for loading post data */ - public function registerRequiresPostData(TControl $control) + public function registerRequiresPostData($control) { - $this->_controlsRegisteredForPostData[$control->getUniqueID()]=true; + $id=is_string($control)?$control:$control->getUniqueID(); + $this->_controlsRegisteredForPostData[$id]=true; + $params=func_get_args(); + foreach($this->getCachingStack() as $item) + $item->registerAction('registerRequiresPostData',$id); } /** @@ -747,8 +755,11 @@ class TPage extends TTemplateControl { if($this->_focus) { - if(($this->_focus instanceof TControl) && $this->_focus->getVisible(true) || is_string($this->_focus)) - $cs->registerFocusControl($this->_focus); + if(($this->_focus instanceof TControl) && $this->_focus->getVisible(true)) + $focus=$this->_focus->getClientID(); + else + $focus=$this->_focus; + $cs->registerFocusControl($focus); } else if($this->_postData && ($lastFocus=$this->_postData->itemAt(self::FIELD_LASTFOCUS))!==null) $cs->registerFocusControl($lastFocus); @@ -908,6 +919,13 @@ class TPage extends TTemplateControl { $this->_pagePath=$value; } + + public function getCachingStack() + { + if(!$this->_cachingStack) + $this->_cachingStack=new TStack; + return $this->_cachingStack; + } } /** diff --git a/framework/Web/UI/WebControls/TOutputCache.php b/framework/Web/UI/WebControls/TOutputCache.php new file mode 100644 index 00000000..9708c033 --- /dev/null +++ b/framework/Web/UI/WebControls/TOutputCache.php @@ -0,0 +1,160 @@ +_cacheReady && !$this->_useCache) + { + $stack=$this->getPage()->getCachingStack(); + $stack->push($this); + parent::initRecursive($namingContainer); + $stack->pop(); + } + else + parent::initRecursive($namingContainer); + } + + protected function loadRecursive() + { + if($this->_cacheReady && !$this->_useCache) + { + $stack=$this->getPage()->getCachingStack(); + $stack->push($this); + parent::loadRecursive(); + $stack->pop(); + } + else + { + if($this->_useCache) + { + $cs=$this->getPage()->getClientScript(); + foreach($this->_actions as $action) + { + if($action[0]==='registerRequiresPostData') + $this->getPage()->registerRequiresPostData($action[1]); + else + call_user_func_array(array($cs,$action[0]),$action[1]); + } + } + parent::loadRecursive(); + } + } + + protected function preRenderRecursive() + { + if($this->_cacheReady && !$this->_useCache) + { + $stack=$this->getPage()->getCachingStack(); + $stack->push($this); + parent::preRenderRecursive(); + $stack->pop(); + } + else + parent::preRenderRecursive(); + } + + public function registerAction($funcName,$funcParams) + { + $this->_actions[]=array($funcName,$funcParams); + } + + public function getAllowChildControls() + { + if(!$this->_cacheChecked) + { + $this->_cacheChecked=true; + if(!$this->getPage()->getIsPostBack() && ($this->_cache=$this->getApplication()->getCache())!==null && $this->getEnableCaching()) + { + $this->_cacheReady=true; + $data=$this->_cache->get($this->getCacheKey()); + if(($this->_useCache=($data!==false))) + list($this->_contents,$this->_state,$this->_actions)=$data; + } + } + return !$this->_useCache; + } + + public function getEnableCaching() + { + return $this->_enableCaching; + } + + public function setEnableCaching($value) + { + $this->_enableCaching=TPropertyValue::ensureBoolean($value); + } + + protected function loadStateRecursive(&$state,$needViewState=true) + { + if($this->_useCache) + parent::loadStateRecursive($this->_state,$needViewState); + else + parent::loadStateRecursive($state,$needViewState); + } + + protected function &saveStateRecursive($needViewState=true) + { + if($this->_useCache) + return $this->_state; + else if($this->_cacheReady) + { + $this->_state=parent::saveStateRecursive($needViewState); + return $this->_state; + } + else + return parent::saveStateRecursive($needViewState); + } + + protected function getCacheKey() + { + return self::CACHE_ID_PREFIX.$this->getUniqueID(); + } + + public function getExpiry() + { + return $this->_expiry; + } + + public function setExpiry($value) + { + if(($value=TPropertyValue::ensureInteger($value))<0) + throw new TInvalidDataValueException('outputcache_expiry_invalid'); + $this->_expiry=$value; + } + + public function render($writer) + { + if($this->_useCache) + $writer->write($this->_contents); + else if($this->_cacheReady) + { + $textWriter=new TTextWriter; + + $stack=$this->getPage()->getCachingStack(); + $stack->push($this); + parent::render(new THtmlWriter($textWriter)); + $stack->pop(); + + $content=$textWriter->flush(); + $data=array($content,$this->_state,$this->_actions); + $this->_cache->set($this->getCacheKey(),$data,$this->getExpiry()); + $writer->write($content); + } + else + parent::render($writer); + } +} + +?> \ No newline at end of file diff --git a/framework/Web/UI/WebControls/TPanel.php b/framework/Web/UI/WebControls/TPanel.php index 5f99edf5..03f0a3a3 100644 --- a/framework/Web/UI/WebControls/TPanel.php +++ b/framework/Web/UI/WebControls/TPanel.php @@ -73,7 +73,7 @@ class TPanel extends TWebControl else { $writer->addAttribute('id',$this->getClientID()); - $this->getPage()->getClientScript()->registerDefaultButton($this, $button); + $this->getPage()->getClientScript()->registerDefaultButton($this->getClientID(), $button->getClientID()); } } } diff --git a/framework/Web/UI/WebControls/TWizard.php b/framework/Web/UI/WebControls/TWizard.php index ef4691bd..0b44872b 100644 --- a/framework/Web/UI/WebControls/TWizard.php +++ b/framework/Web/UI/WebControls/TWizard.php @@ -16,7 +16,6 @@ Prado::using('System.Web.UI.WebControls.TButton'); Prado::using('System.Web.UI.WebControls.TLinkButton'); Prado::using('System.Web.UI.WebControls.TImageButton'); Prado::using('System.Web.UI.WebControls.TDataList'); -Prado::using('System.Collections.TStack'); /** * Class TWizard. -- cgit v1.2.3