summaryrefslogtreecommitdiff
path: root/framework/Web/UI/TPage.php
diff options
context:
space:
mode:
Diffstat (limited to 'framework/Web/UI/TPage.php')
-rw-r--r--framework/Web/UI/TPage.php617
1 files changed, 617 insertions, 0 deletions
diff --git a/framework/Web/UI/TPage.php b/framework/Web/UI/TPage.php
new file mode 100644
index 00000000..bb8f2253
--- /dev/null
+++ b/framework/Web/UI/TPage.php
@@ -0,0 +1,617 @@
+<?php
+
+Prado::using('System.Web.*');
+Prado::using('System.Web.UI.*');
+Prado::using('System.Web.UI.WebControls.*');
+
+class TPage extends TTemplateControl
+{
+ private $_application;
+ private $_contentTemplateCollection=null;
+ private $_maxPageStateFieldLength=10;
+ private $_enableViewStateMac=true;
+ private $_performPreRendering=true;
+ private $_performRendering=true;
+ private $_supportsStyleSheet=true;
+ private $_theme=null;
+ private $_themeName='';
+ private $_styleSheet=null;
+ private $_styleSheetName='';
+
+ private $_clientScript=null;
+ private $_form=null;
+ private $_formRendered=false;
+ private $_inFormRender=false;
+ private $_pageState='';
+ private $_requirePostBackScript=false;
+ private $_postBackScriptRendered=false;
+ private $_isCrossPagePostBack=false;
+ private $_previousPagePath='';
+ private $_preInitWorkComplete=false;
+ private $_changedPostDataConsumers=array();
+ private $_postData;
+ private $_restPostData;
+ private $_pageStateChanged=false;
+ private $_controlsRequiringPostBack=array();
+ private $_registeredControlThatRequireRaiseEvent=null;
+ private $_registeredControlsThatRequirePostBack=null;
+ private $_validators=array();
+ private $_validated=false;
+ private $_autoPostBackControl=null;
+ private $_webFormsScriptRendered=false;
+ private $_requireWebFormsScript=false;
+ private static $_systemPostFields=array('__EVENTTARGET','__EVENTPARAM','__STATE','__PREVPAGE','__CALLBACKID','__CALLBACKPARAM','__LASTFOCUS');
+ private $_contents=array();
+ private $_templateFile=null;
+
+ public function __construct($initProperties=null)
+ {
+ $this->_application=Prado::getApplication();
+ $this->setPage($this);
+ if(is_array($initProperties))
+ {
+ foreach($initProperties as $name=>$value)
+ $this->setPropertyByPath($name,$value);
+ }
+ parent::__construct();
+ }
+
+ /**
+ * Loads and parses the control template
+ * @return ITemplate the parsed template structure
+ */
+ protected function loadTemplate()
+ {
+ if($this->_templateFile===null)
+ return parent::loadTemplate();
+ else
+ {
+ $template=Prado::getApplication()->getService()->getTemplateManager()->loadTemplateByFileName(Prado::getPathOfNamespace($this->_templateFile,'.tpl'));
+ $this->setTemplate($template);
+ return $template;
+ }
+ }
+
+ public function getTemplateFile()
+ {
+ return $this->_templateFile;
+ }
+
+ public function setTemplateFile($value)
+ {
+ $this->_templateFile=$value;
+ }
+
+ final public function setForm($form)
+ {
+ $this->_form=$form;
+ }
+
+ final public function getForm()
+ {
+ return $this->_form;
+ }
+
+ public function validate($validationGroup='')
+ {
+ $this->_validated=true;
+ if($validationGroup==='')
+ {
+ foreach($this->_validators as $validator)
+ $validator->validate();
+ }
+ else
+ {
+ foreach($this->_validators as $validator)
+ if($validator->getValidationGroup()===$validationGroup)
+ $validator->validate();
+ }
+ }
+
+ public function RegisterEnabledControl($control)
+ {
+ $this->getEna.EnabledControls.Add(control);
+ }
+
+
+
+ /**
+ * @internal
+ */
+ public function registerPostBackScript()
+ {
+ if($this->getClientSupportsJavaScript() && !$this->_postBackScriptRendered)
+ {
+ if(!$this->_requirePostBackScript)
+ {
+ $this->getClientScript()->registerHiddenField('__EVENTTARGET','');
+ $this->getClientScript()->registerHiddenField('__EVENTPARAM','');
+ $this->_requirePostBackScript=true;
+ }
+ }
+ }
+
+ public function registerWebFormsScript()
+ {
+ if($this->getClientSupportsJavaScript() && !$this->_webFormsScriptRendered)
+ {
+ $this->registerPostBackScript();
+ $this->_requireWebFormsScript=true;
+ }
+ }
+
+
+ public function ensureRenderInForm($control)
+ {
+ if(!$this->_inFormRender)
+ throw new THttpException('control_not_in_form',$control->getUniqueID());
+ }
+
+ /**
+ * @internal
+ */
+ final protected function addContentTemplate($name,$template)
+ {
+ if(!$this->_contentTemplateCollection)
+ $this->_contentTemplateCollection=new TMap;
+ if($this->_contentTemplateCollection->has($name))
+ throw new Exception("Content '$name' duplicated.");
+ $this->_contentTemplateCollection->add($name,$template);
+ }
+
+ /**
+ * @internal
+ */
+ final public function applyControlSkin($control)
+ {
+ if($this->_theme)
+ $this->_theme->applySkin($control);
+ }
+
+ /**
+ * @internal
+ */
+ final public function applyControlStyleSheet($control)
+ {
+ if($this->_styleSheet)
+ {
+ $this->_styleSheet->applySkin($control);
+ return true;
+ }
+ else
+ return false;
+ }
+
+ private function renderStateFields($writer)
+ {
+ $writer->write("\n<input type=\"hidden\" name=\"__STATE\" id=\"__STATE\" value=\"".$this->_pageState."\" />\n");
+ }
+
+ private function renderPostBackScript($writer)
+ {
+ $id=$this->_form->getUniqueID();
+ $str=<<<EOD
+\n<script type="text/javascript">
+<!--
+var theForm=document.forms['$id'];
+if(!theForm)
+ theForm=document.$id;
+function __doPostBack(eventTarget,eventParam) {
+ if(!theForm.onsubmit || (theForm.onsubmit()!=false)) {
+ theForm.__EVENTTARGET.value = eventTarget;
+ theForm.__EVENTPARAM.value = eventParam;
+ theForm.submit();
+ }
+}
+// -->
+</script>\n
+EOD;
+ $writer->write($str);
+ $this->_postBackScriptRendered=true;
+ }
+
+ private function renderWebFormsScript($writer)
+ {
+ $writer->write("\n<script src=\"js/WebForms.js\" type=\"text/javascript\"></script>\n");
+ $this->_webFormsScriptRendered=true;
+ }
+
+ final public function getClientSupportsJavaScript()
+ {
+ // todo
+ return true;
+ }
+
+ /**
+ * @internal
+ */
+ final public function beginFormRender($writer)
+ {
+ if($this->_formRendered)
+ throw new THttpException('multiple_form_not_allowed');
+ $this->_formRendered=true;
+ $this->_inFormRender=true;
+
+ $this->getClientScript()->renderHiddenFields($writer);
+ //$this->renderStateFields($writer);
+ if($this->getClientSupportsJavaScript())
+ {
+ /*
+ if($this->getMaintainScrollPositionOnPostBack() && !$this->_requireScrollScript)
+ {
+ $cs=$this->getClientScript();
+ $cs->registerHiddenField('_SCROLLPOSITIONX',$this->_scrollPositionX);
+ $cs->registerHiddenField('_SCROLLPOSITIONY',$this->_scrollPositionY);
+ $cs->registerStartupScript(get_class($this),"PageScrollPositionScript", "\r\nvar WebForm_ScrollPositionSubmit = theForm.submit;\r\ntheForm.submit = WebForm_SaveScrollPositionSubmit;\r\n\r\nvar WebForm_ScrollPositionOnSubmit = theForm.onsubmit;\r\ntheForm.onsubmit = WebForm_SaveScrollPositionOnSubmit;\r\n\r\nvar WebForm_ScrollPositionLoad = window.onload;\r\nwindow.onload = WebForm_RestoreScrollPosition;\r\n", true);
+ $this->registerWebFormScript();
+ $this->_requireScrollScript=true;
+ }
+ */
+ if($this->_requirePostBackScript)
+ $this->renderPostBackScript($writer,$this->_form->getUniqueID());
+ if($this->_requireWebFormsScript)
+ $this->renderWebFormsScript($writer);
+ }
+ $this->getClientScript()->renderClientScriptBlocks($writer);
+ // todo: more ....
+ }
+
+ final public function getIsPostBackEventControlRegistered()
+ {
+ return $this->_registeredControlThatRequireRaiseEvent!==null;
+ }
+
+ /**
+ * @internal
+ */
+ final public function endFormRender($writer)
+ {
+ $cs=$this->getClientScript();
+ if($this->getClientSupportsJavaScript())
+ $cs->renderArrayDeclarations($writer);
+ $cs->renderHiddenFields($writer);
+ if($this->getClientSupportsJavaScript())
+ {
+ if($this->_requirePostBackScript && !$this->_postBackScriptRendered)
+ $this->renderPostBackScript($writer);
+ if($this->_requireWebFormsScript && !$this->_webFormsScriptRendered)
+ $this->renderWebFormsScript($writer);
+ }
+ $cs->renderClientStartupScripts($writer);
+ $this->_inFormRender=false;
+ }
+
+ final public function getClientScript()
+ {
+ if(!$this->_clientScript)
+ $this->_clientScript=new TClientScriptManager($this);
+ return $this->_clientScript;
+ }
+
+ final public function getClientOnSubmitEvent()
+ {
+ // todo
+ if($this->getClientScript()->getHasSubmitStatements())
+ return 'javascript:return WebForm_OnSubmit();';
+ else
+ return '';
+ }
+
+ final public function getValidators($validationGroup='')
+ {
+ if(!$this->_validators)
+ $this->_validators=new TList;
+ if($validationGroup==='')
+ return $this->_validators;
+ $list=new TList;
+ foreach($this->_validators as $validator)
+ if($validator->getValidationGroup()===$validationGroup)
+ $list->add($validator);
+ return $list;
+ }
+
+ protected function initializeCulture()
+ {
+ }
+
+ /**
+ * @internal
+ */
+ public function initializeStyleSheet()
+ {
+ if($this->_styleSheet!=='')
+ $this->_styleSheet=new TTheme($this->_styleSheetName);
+ }
+
+ private function initializeThemes()
+ {
+ if($this->_themeName!=='')
+ $this->_theme=new TTheme($this->_themeName);
+ if($this->_styleSheetName!=='')
+ $this->_styleSheet=new TTheme($this->_styleSheetName);
+ }
+
+ /**
+ * @internal
+ */
+ public function loadScrollPosition()
+ {
+ if($this->_previousPagePath==='' && $this->_requestValueCollection)
+ {
+ if(isset($_REQUEST['__SCROLLPOSITIONX']))
+ $this->_scrollPositionX=(integer)$_REQUEST['__SCROLLPOSITIONX'];
+ if(isset($_REQUEST['__SCROLLPOSITIONY']))
+ $this->_scrollPositionX=(integer)$_REQUEST['__SCROLLPOSITIONY'];
+ }
+ }
+
+ protected function onInit($param)
+ {
+ parent::onInit($param);/*
+ if($this->_theme)
+ $this->_theme->setStyleSheet();
+ if($this->_styleSheet)
+ $this->_styleSheet->setStyleSheet();*/
+ }
+
+ protected function onInitComplete($param)
+ {
+ $this->raiseEvent('InitComplete',$this,$param);
+ }
+
+ protected function onLoadComplete($param)
+ {
+ $this->raiseEvent('LoadComplete',$this,$param);
+ }
+
+ protected function onPreInit($param)
+ {
+ $this->raiseEvent('PreInit',$this,$param);
+ }
+
+ protected function onPreLoad($param)
+ {
+ $this->raiseEvent('PreLoad',$this,$param);
+ }
+
+ protected function onPreRenderComplete($param)
+ {
+ $this->raiseEvent('PreRenderComplete',$this,$param);
+ }
+
+ protected function onSaveStateComplete($param)
+ {
+ $this->raiseEvent('SaveStateComplete',$this,$param);
+ }
+
+ final public function registerAsyncTask()
+ {
+ }
+
+ final public function registerRequiresPostBack($control)
+ {
+ if(!$this->_registeredControlsThatRequirePostBack)
+ $this->_registeredControlsThatRequirePostBack=new TList;
+ $this->_registeredControlsThatRequirePostBack->add($control->getUniqueID());
+ }
+
+ final public function registerRequiresRaiseEvent($control)
+ {
+ $this->_registeredControlThatRequireRaiseEvent=$control;
+ }
+
+ public function getApplication()
+ {
+ return $this->_application;
+ }
+
+ public function loadStateField()
+ {
+ return base64_decode($this->_postData->itemAt('__STATE'));
+ }
+
+ public function saveStateField($state)
+ {
+ $this->getClientScript()->registerHiddenField('__STATE',base64_encode($state));
+ }
+
+ protected function determinePostBackMode()
+ {
+ /*
+ $application=$this->getApplication();
+ if($application->getPreventPostBack())
+ return null;
+ */
+ $postData=new TMap($this->_application->getRequest()->getItems());
+ if($postData->itemAt('__STATE')!==null || $postData->itemAt('__EVENTTARGET')!==null)
+ return $postData;
+ else
+ return null;
+ }
+
+ final public function getIsPostBack()
+ {
+ if($this->_postData)
+ {
+ if($this->_isCrossPagePostBack)
+ return true;
+ if($this->_previousPagePath!=='')
+ return false;
+ return !$this->_pageStateChanged;
+ }
+ else
+ return false;
+ }
+
+ protected function getPageStatePersister()
+ {
+ require_once(PRADO_DIR.'/Web/UI/THiddenFieldPageStatePersister.php');
+ return new THiddenFieldPageStatePersister($this);
+ }
+
+ protected function loadPageState()
+ {
+ $persister=$this->getPageStatePersister();
+ $state=$persister->load();
+ $this->loadStateRecursive($state,$this->getEnableViewState());
+ }
+
+ protected function savePageState()
+ {
+ $state=&$this->saveStateRecursive($this->getEnableViewState());
+ $persister=$this->getPageStatePersister();
+ $persister->save($state);
+ }
+
+ protected function processPostData($postData,$beforeLoad)
+ {
+ $eventTarget=$postData->itemAt('__EVENTTARGET');
+ foreach($postData as $key=>$value)
+ {
+ if(in_array($key,self::$_systemPostFields))
+ continue;
+ else if($control=$this->findControl($key))
+ {
+ if($control instanceof IPostBackDataHandler)
+ {
+ if($control->loadPostData($key,$this->_postData))
+ $this->_changedPostDataConsumers[]=$control;
+ unset($this->_controlsRequiringPostBack[$key]);
+ }
+ else
+ {
+ if(empty($eventTarget))
+ {
+ if($control instanceof IPostBackEventHandler)
+ $this->registerRequiresRaiseEvent($control);
+ }
+ else
+ unset($this->_controlsRequiringPostBack[$key]);
+ }
+ }
+ else if($beforeLoad)
+ $this->_restPostData->add($key,$value);
+ }
+ $list=new TMap;
+ foreach($this->_controlsRequiringPostBack as $key=>$value)
+ {
+ if($control=$this->findControl($key))
+ {
+ if($control instanceof IPostBackDataHandler)
+ {
+ if($control->loadPostData($key,$this->_postData))
+ $this->_changedPostDataConsumers->add($control);
+ }
+ else
+ throw new THttpException('postback_control_not_found',$key);
+ }
+ else if($beforeLoad)
+ $list->add($key,null);
+ }
+ $this->_controlsRequiringPostBack=$list;
+ }
+
+ final public function getAutoPostBackControl()
+ {
+ return $this->_autoPostBackControl;
+ }
+
+ final public function setAutoPostBackControl($control)
+ {
+ $this->_autoPostBackControl=$control;
+ }
+
+ private function raiseChangedEvents()
+ {
+ foreach($this->_changedPostDataConsumers as $control)
+ $control->raisePostDataChangedEvent();
+ }
+
+ private function raisePostBackEvent($postData)
+ {
+ if($this->_registeredControlThatRequireRaiseEvent)
+ {
+ $this->_registeredControlThatRequireRaiseEvent->raisePostBackEvent(null);
+ }
+ else
+ {
+ $eventTarget=$postData->itemAt('__EVENTTARGET');
+ if(!empty($eventTarget) || $this->getAutoPostBackControl())
+ {
+ if(!empty($eventTarget))
+ $control=$this->findControl($eventTarget);
+ else
+ $control=null;
+ if($control instanceof IPostBackEventHandler)
+ $control->raisePostBackEvent($postData->itemAt('__EVENTPARAM'));
+ }
+ else
+ $this->validate();
+ }
+ }
+
+ public function run($writer)
+ {
+ $this->_postData=$this->determinePostBackMode();
+ $this->_restPostData=new TMap;
+
+ $this->onPreInit(null);
+ $this->initializeThemes();
+ $this->_preInitWorkComplete=true;
+
+ $this->initRecursive(null);
+ $this->onInitComplete(null);
+
+ if($this->getIsPostBack())
+ {
+ $this->loadPageState();
+ $this->processPostData($this->_postData,true);
+ }
+
+ $this->onPreLoad(null);
+ $this->loadRecursive(null);
+ if($this->getIsPostBack())
+ {
+ $this->processPostData($this->_restPostData,false);
+ $this->raiseChangedEvents();
+ $this->raisePostBackEvent($this->_postData);
+ }
+ $this->onLoadComplete(null);
+
+ $this->preRenderRecursive();
+ $this->onPreRenderComplete(null);
+
+ $this->savePageState();
+ $this->onSaveStateComplete(null);
+
+ $this->renderControl($writer);
+ $this->unloadRecursive();
+ }
+
+ public function getTheme()
+ {
+ return $this->_themeName;
+ }
+
+ public function setTheme($value)
+ {
+ $this->_themeName=$value;
+ }
+
+ public function getStyleSheetTheme()
+ {
+ return $this->_styleSheetName;
+ }
+
+ public function setStyleSheetTheme($value)
+ {
+ $this->_styleSheetName=$value;
+ }
+
+ public function getContainsTheme()
+ {
+ return $this->_theme!==null;
+ }
+}
+
+?> \ No newline at end of file