diff options
| -rw-r--r-- | framework/PradoBase.php | 2 | ||||
| -rw-r--r-- | framework/Web/UI/TPage.php | 104 | ||||
| -rw-r--r-- | framework/Web/UI/TPageStatePersister.php | 44 | 
3 files changed, 113 insertions, 37 deletions
| 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);
 @@ -842,6 +847,34 @@ class TPage extends TTemplateControl  	}
  	/**
 +	 * 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()
 @@ -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');
  	}
  }
 | 
