summaryrefslogtreecommitdiff
path: root/framework/Web
diff options
context:
space:
mode:
Diffstat (limited to 'framework/Web')
-rw-r--r--framework/Web/UI/TClientScriptManager.php95
-rw-r--r--framework/Web/UI/TControl.php12
-rw-r--r--framework/Web/UI/TForm.php2
-rw-r--r--framework/Web/UI/TPage.php26
-rw-r--r--framework/Web/UI/WebControls/TOutputCache.php160
-rw-r--r--framework/Web/UI/WebControls/TPanel.php2
-rw-r--r--framework/Web/UI/WebControls/TWizard.php1
7 files changed, 262 insertions, 36 deletions
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
@@ -116,6 +116,15 @@ class TClientScriptManager extends TApplicationComponent
*/
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]))
{
$this->_registeredPradoScripts[$name]=true;
@@ -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 @@
+<?php
+
+class TOutputCache extends TControl implements INamingContainer
+{
+ const CACHE_ID_PREFIX='prado:outputcache';
+ private $_useCache=false;
+ private $_cacheReady=false;
+ private $_cacheChecked=false;
+ private $_expiry=60;
+ private $_cache=null;
+ private $_contents;
+ private $_state;
+ private $_enableCaching=true;
+ private $_actions=array();
+
+ protected function initRecursive($namingContainer=null)
+ {
+ if($this->_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.