From 37f4d81a1ce6bdea84b00a38b0c8fc32f82f9e5d Mon Sep 17 00:00:00 2001
From: xue <>
Date: Tue, 11 Apr 2006 00:58:46 +0000
Subject: Refactored page state persister.

---
 framework/PradoBase.php                  |   2 +-
 framework/Web/UI/TPage.php               | 104 ++++++++++++++++++++++++++++++-
 framework/Web/UI/TPageStatePersister.php |  44 +++----------
 3 files changed, 113 insertions(+), 37 deletions(-)

(limited to 'framework')

diff --git a/framework/PradoBase.php b/framework/PradoBase.php
index 5325005a..0baa9234 100644
--- a/framework/PradoBase.php
+++ b/framework/PradoBase.php
@@ -68,7 +68,7 @@ class PradoBase
 	 */
 	public static function getVersion()
 	{
-		return '3.0RC1';
+		return '3.1.0b';
 	}
 
 	/**
diff --git a/framework/Web/UI/TPage.php b/framework/Web/UI/TPage.php
index 6a4083b0..e34101d9 100644
--- a/framework/Web/UI/TPage.php
+++ b/framework/Web/UI/TPage.php
@@ -145,6 +145,10 @@ class TPage extends TTemplateControl
 	 * @var TStack stack used to store currently active caching controls
 	 */
 	private $_cachingStack=null;
+	/**
+	 * @var string state string to be stored on the client side
+	 */
+	private $_clientState='';
 
 	/**
 	 * Constructor.
@@ -740,6 +744,7 @@ class TPage extends TTemplateControl
 		$this->_formRendered=true;
 		$this->_inFormRender=true;
 		$cs=$this->getClientScript();
+		$cs->registerHiddenField(self::FIELD_PAGESTATE,$this->getClientState());
 		$cs->renderHiddenFields($writer);
 		$cs->renderScriptFiles($writer);
 		$cs->renderBeginScripts($writer);
@@ -841,6 +846,34 @@ class TPage extends TTemplateControl
 			$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.
 	 */
@@ -937,7 +970,7 @@ class TPage extends TTemplateControl
  * @author Qiang Xue <qiang.xue@gmail.com>
  * @version $Revision: $  $Date: $
  * @package System.Web.UI
- * @since 3.0
+ * @since 3.1
  */
 interface IPageStatePersister
 {
@@ -961,4 +994,73 @@ interface IPageStatePersister
 	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($page->getEnableStateEncryption())
+			$str=$sm->encrypt($str);
+		if(extension_loaded('zlib'))
+			$str=gzcompress($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(extension_loaded('zlib'))
+			$str=gzuncompress($str);
+		if($str!==false)
+		{
+			$sm=$page->getApplication()->getSecurityManager();
+			if($page->getEnableStateEncryption())
+				$str=$sm->decrypt($str);
+			if($page->getEnableStateValidation())
+			{
+				if(($str=$sm->validateData($str))!==false)
+					return Prado::unserialize($str);
+			}
+			else
+				return $str;
+		}
+		return null;
+	}
+}
+
 ?>
\ No newline at end of file
diff --git a/framework/Web/UI/TPageStatePersister.php b/framework/Web/UI/TPageStatePersister.php
index 3551b5f6..ff5b088b 100644
--- a/framework/Web/UI/TPageStatePersister.php
+++ b/framework/Web/UI/TPageStatePersister.php
@@ -16,19 +16,17 @@
  * TPageStatePersister implements a page state persistent method based on
  * form hidden fields.
  *
- * Depending on the {@link TPage::getEnableStateValidation() EnableStateValidation}
- * and {@link TPage::getEnableStateEncryption() EnableStateEncryption},
- * TPageStatePersister 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}.
+ * Since page state can be very big for complex pages, consider using
+ * alternative persisters, such as {@link TSessionPageStatePersister},
+ * which store page state on the server side and thus reduce the network
+ * traffic for transmitting bulky page state.
  *
  * @author Qiang Xue <qiang.xue@gmail.com>
  * @version $Revision: $  $Date: $
  * @package System.Web.UI
  * @since 3.0
  */
-class TPageStatePersister extends TApplicationComponent implements IPageStatePersister
+class TPageStatePersister extends TComponent implements IPageStatePersister
 {
 	private $_page;
 
@@ -54,15 +52,7 @@ class TPageStatePersister extends TApplicationComponent implements IPageStatePer
 	 */
 	public function save($state)
 	{
-		if($this->_page->getEnableStateValidation())
-			$data=$this->getApplication()->getSecurityManager()->hashData(Prado::serialize($state));
-		else
-			$data=Prado::serialize($state);
-		if($this->_page->getEnableStateEncryption())
-			$data=$this->getApplication()->getSecurityManager()->encrypt($data);
-		if(extension_loaded('zlib'))
-			$data=gzcompress($data);
-		$this->_page->getClientScript()->registerHiddenField(TPage::FIELD_PAGESTATE,base64_encode($data));
+		$this->_page->setClientState(TPageStateFormatter::serialize($this->_page,$state));
 	}
 
 	/**
@@ -72,26 +62,10 @@ class TPageStatePersister extends TApplicationComponent implements IPageStatePer
 	 */
 	public function load()
 	{
-		$str=base64_decode($this->getRequest()->itemAt(TPage::FIELD_PAGESTATE));
-		if($str==='')
-			return null;
-		if(extension_loaded('zlib'))
-			$data=gzuncompress($str);
+		if(($data=TPageStateFormatter::unserialize($this->_page,$this->_page->getRequestClientState()))!==null)
+			return $data;
 		else
-			$data=$str;
-		if($data!==false)
-		{
-			if($this->_page->getEnableStateEncryption())
-				$data=$this->getApplication()->getSecurityManager()->decrypt($data);
-			if($this->_page->getEnableStateValidation())
-			{
-				if(($data=$this->getApplication()->getSecurityManager()->validateData($data))!==false)
-					return Prado::unserialize($data);
-			}
-			else
-				return $data;
-		}
-		throw new THttpException(400,'pagestatepersister_pagestate_corrupted');
+			throw new THttpException(400,'pagestatepersister_pagestate_corrupted');
 	}
 }
 
-- 
cgit v1.2.3