summaryrefslogtreecommitdiff
path: root/framework/Web/UI
diff options
context:
space:
mode:
Diffstat (limited to 'framework/Web/UI')
-rw-r--r--framework/Web/UI/ActiveControls/TActiveControl.php28
-rw-r--r--framework/Web/UI/ActiveControls/TActiveControlAdapter.php2
-rw-r--r--framework/Web/UI/ActiveControls/TActivePageAdapter.php164
-rw-r--r--framework/Web/UI/ActiveControls/TCallbackClientScript.php4
-rw-r--r--framework/Web/UI/ActiveControls/TCallbackClientSideOptions.php209
-rw-r--r--framework/Web/UI/ActiveControls/TCallbackResponse.php3
-rw-r--r--framework/Web/UI/TClientScriptManager.php15
-rw-r--r--framework/Web/UI/TControl.php7
-rw-r--r--framework/Web/UI/TPage.php19
9 files changed, 391 insertions, 60 deletions
diff --git a/framework/Web/UI/ActiveControls/TActiveControl.php b/framework/Web/UI/ActiveControls/TActiveControl.php
index d289bab9..e61682d3 100644
--- a/framework/Web/UI/ActiveControls/TActiveControl.php
+++ b/framework/Web/UI/ActiveControls/TActiveControl.php
@@ -6,17 +6,43 @@
class TActiveControl extends TControl implements ICallbackEventHandler, IActiveControl
{
+ private $_clientSide;
+
public function __construct()
{
parent::__construct();
$this->setAdapter(new TActiveControlAdapter($this));
}
+
+ public function getClientSide()
+ {
+ if(is_null($this->_clientSide))
+ $this->_clientSide = $this->createClientSideOptions();
+ return $this->_clientSide;
+ }
+
+ protected function createClientSideOptions()
+ {
+ $client = new TCallbackClientSideOptions;
+ return $client;
+ }
public function raiseCallbackEvent($param)
{
- var_dump($param);
+ var_dump($param->getParameter());
+ $param->Output->write($param->Parameter);
$client = $this->getPage()->getCallbackClient();
$client->hide($this);
+ $client->toggle($this);
+ $client->update($this, 1);
+ $param->setData(array("asdasdad",1));
+ }
+
+ public function getCallbackReference()
+ {
+ // $formID = $this->getPage()->getForm()->getClientID();
+ // $this->getClientSide()->setValidationForm($formID);
+ return $this->getPage()->getClientScript()->getCallbackReference($this);
}
}
diff --git a/framework/Web/UI/ActiveControls/TActiveControlAdapter.php b/framework/Web/UI/ActiveControls/TActiveControlAdapter.php
index 187b2cac..b95bdd37 100644
--- a/framework/Web/UI/ActiveControls/TActiveControlAdapter.php
+++ b/framework/Web/UI/ActiveControls/TActiveControlAdapter.php
@@ -15,7 +15,7 @@ class TActiveControlAdapter extends TControlAdapter
if(!self::$_renderedPosts)
{
$options = TJavascript::encode($this->getPage()->getPostDataLoaders(),false);
- $script = "Prado.Callback.PostDataLoaders.concat({$options});";
+ $script = "Prado.CallbackRequest.PostDataLoaders.concat({$options});";
$this->getPage()->getClientScript()->registerEndScript(get_class($this), $script);
self::$_renderedPosts = true;
}
diff --git a/framework/Web/UI/ActiveControls/TActivePageAdapter.php b/framework/Web/UI/ActiveControls/TActivePageAdapter.php
index ab042d54..2607fec2 100644
--- a/framework/Web/UI/ActiveControls/TActivePageAdapter.php
+++ b/framework/Web/UI/ActiveControls/TActivePageAdapter.php
@@ -22,6 +22,10 @@
*/
class TActivePageAdapter extends TControlAdapter
{
+ const CALLBACK_DATA_HEADER = 'X-PRADO-DATA';
+ const CALLBACK_ACTION_HEADER = 'X-PRADO-ACTIONS';
+ const CALLBACK_ERROR_HEADER = 'X-PRADO-ERROR';
+
/**
* @var ICallbackEventHandler callback event handler.
*/
@@ -35,11 +39,9 @@ class TActivePageAdapter extends TControlAdapter
*/
private $_callbackClient;
/**
- * @var TCallbackResponse callback response handler.
+ * @var TCallbackEventParameter callback result.
*/
- private $_callbackResponse;
-
- private $_callbackEventResult;
+ private $_result;
/**
* Constructor, trap errors and exception to let the callback response
@@ -48,6 +50,7 @@ class TActivePageAdapter extends TControlAdapter
public function __construct(TPage $control)
{
parent::__construct($control);
+ //$this->getApplication()->setResponse($this->getCallbackResponseHandler());
$this->trapCallbackErrorsExceptions();
}
@@ -62,36 +65,36 @@ class TActivePageAdapter extends TControlAdapter
protected function trapCallbackErrorsExceptions()
{
- //TODO: How to trap the errors and exceptions and return them
- // as part of the response.
+ $this->getApplication()->setErrorHandler(new TCallbackErrorHandler);
}
+ /**
+ * Render the callback response.
+ */
public function renderCallbackResponse($writer)
{
Prado::trace("ActivePage renderCallbackResponse()",'System.Web.UI.ActiveControls.TActivePageAdapter');
$this->renderResponse($writer);
}
+ /**
+ * Renders the callback response by adding additional callback data and
+ * javascript actions in the header.
+ */
protected function renderResponse($writer)
{
- //var_dump(getallheaders());
- //TODO: How to render the response, it will contain 3 pieces of data
- // 1) The arbituary data returned to the client-side callback handler
- // 2) client-side function call statements
- // 3) Content body, which may need to be partitioned
-
- /*
- $response = $this->getCallbackResponseHandler();
- $response->writeClientScriptResponse($this->getCallbackClientHandler());
- $response->writeResponseData($this->getCallbackEventResult());
- $response->flush();
- */
+ $response = $this->getResponse();
+ $executeJavascript = $this->getCallbackClientHandler()->getClientFunctionsToExecute()->toArray();
+ $actions = TJavascript::jsonEncode($executeJavascript);
+ $response->appendHeader(self::CALLBACK_ACTION_HEADER.': '.$actions);
+ $data = TJavascript::jsonEncode($this->_result->getData());
+ $response->appendHeader(self::CALLBACK_DATA_HEADER.': '.$data);
+ $response->flush();
}
/**
* Trys to find the callback event handler and raise its callback event.
- * @throws TInvalidCallbackRequestException if call back target is not
- * found.
+ * @throws TInvalidCallbackRequestException if call back target is not found.
* @throws TInvalidCallbackHandlerException if the requested target does not
* implement ICallbackEventHandler.
*/
@@ -100,7 +103,11 @@ class TActivePageAdapter extends TControlAdapter
if(($callbackHandler=$this->getCallbackEventTarget())!==null)
{
if($callbackHandler instanceof ICallbackEventHandler)
- $callbackHandler->raiseCallbackEvent($this->getCallbackEventParameter());
+ {
+ $writer = $this->getResponse()->createHtmlWriter();
+ $this->_result = new TCallbackEventParameter($writer, $this->getCallbackEventParameter());
+ $callbackHandler->raiseCallbackEvent($this->_result);
+ }
else
throw new TInvalidCallbackHandlerException($callbackHandler->getUniqueID());
}
@@ -154,7 +161,6 @@ class TActivePageAdapter extends TControlAdapter
$param = $this->getRequest()->itemAt(TPage::FIELD_CALLBACK_PARAMETER);
if(strlen($param) > 0)
$this->_callbackEventParameter=TJavascript::jsonDecode((string)$param);
- var_dump($param);
}
return $this->_callbackEventParameter;
}
@@ -187,23 +193,119 @@ class TActivePageAdapter extends TControlAdapter
$this->_callbackClient = $handler;
}
+}
+
+/**
+ * TCallbackEventParameter class.
+ *
+ * The TCallbackEventParameter provides the parameter passed during the callback
+ * requestion in the {@link getParameter Parameter} property. The
+ * callback response response content (e.g. new HTML content) can be written to
+ * the {@link getOutput Output} property, which returns an instance of
+ * THtmlWriter. The response data (i.e., passing results back to the client-side
+ * callback handler function) can be set using {@link setData Data} property.
+ *
+ * @author Wei Zhuo <weizhuo[at]gamil[dot]com>
+ * @version $Revision: $ $Date: $
+ * @package System.Web.UI.ActiveControls
+ * @since 3.0
+ */
+class TCallbackEventParameter extends TEventParameter
+{
+ /**
+ * @var THtmlWriter output content.
+ */
+ private $_output;
+ /**
+ * @var mixed callback request parameter.
+ */
+ private $_parameter;
+ /**
+ * @var mixed callback response data.
+ */
+ private $_data;
+
+ /**
+ * Creates a new TCallbackEventParameter.
+ */
+ public function __construct($writer, $parameter)
+ {
+ $this->_output = $writer;
+ $this->_parameter = $parameter;
+ }
+
+ /**
+ * @return THtmlWriter holds the response content.
+ */
+ public function getOutput()
+ {
+ return $this->_output;
+ }
+
/**
- * Gets the callback response handler.
- * @return TCallbackResponse callback response
+ * @return mixed callback request parameter.
*/
- public function getCallbackResponseHandler()
+ public function getParameter()
{
- if(is_null($this->_callbackResponse))
- $this->_callbackResponse = new TCallbackResponse;
- return $this->_callbackResponse;
+ return $this->_parameter;
}
/**
- * @param TCallbackResponse new callback response handler.
+ * @param mixed callback response data.
*/
- public function setCallbackResponseHandler($handler)
+ public function setData($value)
{
- $this->_callbackResponse = $handler;
+ $this->_data = $value;
+ }
+
+ /**
+ * @return mixed callback response data.
+ */
+ public function getData()
+ {
+ return $this->_data;
+ }
+}
+
+class TCallbackErrorHandler extends TErrorHandler
+{
+ protected function displayException($exception)
+ {
+ if($this->getApplication()->getMode()===TApplication::STATE_DEBUG)
+ {
+ $response = $this->getApplication()->getResponse();
+ $data = TJavascript::jsonEncode($this->getExceptionData($exception));
+ $response->appendHeader('HTTP/1.0 505 Internal Error');
+ $response->appendHeader(TActivePageAdapter::CALLBACK_ERROR_HEADER.': '.$data);
+ }
+ else
+ {
+ error_log("Error happened while processing an existing error:\n".$exception->__toString());
+ header('HTTP/1.0 500 Internal Error');
+ }
+ }
+
+ private function getExceptionData($exception)
+ {
+ $data['code']=$exception->getCode() > 0 ? $exception->getCode() : 505;
+ $data['file']=$exception->getFile();
+ $data['line']=$exception->getLine();
+ $data['trace']=$exception->getTrace();
+ if($exception instanceof TPhpErrorException)
+ {
+ // if PHP exception, we want to show the 2nd stack level context
+ // because the 1st stack level is of little use (it's in error handler)
+ if(isset($trace[0]) && isset($trace[0]['file']) && isset($trace[0]['line']))
+ {
+ $data['file']=$trace[0]['file'];
+ $data['line']=$trace[0]['line'];
+ }
+ }
+ $data['type']=get_class($exception);
+ $data['message']=$exception->getMessage();
+ $data['version']=$_SERVER['SERVER_SOFTWARE'].' '.Prado::getVersion();
+ $data['time']=@strftime('%Y-%m-%d %H:%M',time());
+ return $data;
}
}
diff --git a/framework/Web/UI/ActiveControls/TCallbackClientScript.php b/framework/Web/UI/ActiveControls/TCallbackClientScript.php
index 550c88b5..10c0e638 100644
--- a/framework/Web/UI/ActiveControls/TCallbackClientScript.php
+++ b/framework/Web/UI/ActiveControls/TCallbackClientScript.php
@@ -63,10 +63,8 @@ class TCallbackClientScript
*/
public function callClientFunction($function, $params=null)
{
- if(!is_array($params) && $params !== null)
+ if(!is_array($params))
$params = array($params);
- else
- $params = array();
if(count($params) > 0)
{
diff --git a/framework/Web/UI/ActiveControls/TCallbackClientSideOptions.php b/framework/Web/UI/ActiveControls/TCallbackClientSideOptions.php
new file mode 100644
index 00000000..dea1b4e1
--- /dev/null
+++ b/framework/Web/UI/ActiveControls/TCallbackClientSideOptions.php
@@ -0,0 +1,209 @@
+<?php
+/*
+ * Created on 1/05/2006
+ */
+
+class TClientSideOptions extends TComponent
+{
+ private $_options;
+
+ public function __construct()
+ {
+ $this->_options = Prado::createComponent('System.Collections.TMap');
+ }
+
+ protected function setFunction($name, $code)
+ {
+ $this->_options->add($name, $this->ensureFunction($code));
+ }
+
+ protected function getOption($name)
+ {
+ return $this->_options->itemAt($name);
+ }
+
+ public function getOptions()
+ {
+ return $this->_options;
+ }
+
+ protected function ensureFunction($javascript)
+ {
+ return $javascript;
+ }
+}
+
+/**
+ * The following client side events are executing in order if the callback
+ * request and response are send and received successfuly.
+ *
+ * - <b>onUninitialized</b> executed when AJAX request is uninitialized.
+ * - <b>onLoading</b> executed when AJAX request is initiated
+ * - <b>onLoaded</b> executed when AJAX request begins.
+ * - <b>onInteractive</b> executed when AJAX request is in progress.
+ * - <b>onComplete</b>executed when AJAX response returns.
+ *
+ * The <tt>OnSuccess</tt> and <tt>OnFailure</tt> events are raised when the
+ * response is returned. A successful request/response will raise
+ * <tt>OnSuccess</tt> event otherwise <tt>OnFailure</tt> will be raised.
+ *
+ * - <b>onSuccess</b> executed when AJAX request returns and is successful.
+ * - <b>onFailure</b> executed when AJAX request returns and fails.
+ *
+ * - <b>CausesValidation</b> true to perform before callback request.
+ * - <b>ValidationGroup</b> validation grouping name.
+ */
+class TCallbackClientSideOptions extends TClientSideOptions
+{
+ protected function ensureFunction($javascript)
+ {
+ if(TJavascript::isFunction($javascript))
+ return $javascript;
+ else
+ {
+ $code = "function(request, result){ {$javascript} }";
+ return TJavascript::quoteFunction($code);
+ }
+ }
+
+ /**
+ * @return string javascript code for client-side onUninitialized event
+ */
+ public function getOnUninitialized()
+ {
+ return $this->getOption('onUninitialized');
+ }
+
+ /**
+ * @param string javascript code for client-side onUninitialized event.
+ */
+ public function setOnUninitialized($javascript)
+ {
+ $this->setFunction('onUninitialized', $javascript);
+ }
+
+ /**
+ * @return string javascript code for client-side onLoading event
+ */
+ public function getOnLoading()
+ {
+ return $this->getOption('onLoading');
+ }
+
+ /**
+ * @param string javascript code for client-side onLoading event.
+ */
+ public function setOnLoading($javascript)
+ {
+ $this->setFunction('onLoading', $javascript);
+ }
+
+ /**
+ * @return string javascript code for client-side onLoaded event
+ */
+ public function getOnLoaded()
+ {
+ return $this->getOption('onLoaded');
+ }
+
+ /**
+ * @param string javascript code for client-side onLoaded event.
+ */
+ public function setOnLoaded($javascript)
+ {
+ $this->setFunction('onLoaded', $javascript);
+ }
+ /**
+ * @return string javascript code for client-side onInteractive event
+ */
+ public function getOnInteractive()
+ {
+ return $this->getOption('onInteractive');
+ }
+
+ /**
+ * @param string javascript code for client-side onInteractive event.
+ */
+ public function setonInteractive($javascript)
+ {
+ $this->setFunction('onInteractive', $javascript);
+ }
+ /**
+ * @return string javascript code for client-side onComplete event
+ */
+ public function getOnComplete()
+ {
+ return $this->getOption('onComplete');
+ }
+
+ /**
+ * @param string javascript code for client-side onComplete event.
+ */
+ public function setOnComplete($javascript)
+ {
+ $this->setFunction('onComplete', $javascript);
+ }
+ /**
+ * @return string javascript code for client-side onSuccess event
+ */
+ public function getOnSuccess()
+ {
+ return $this->getOption('onSuccess');
+ }
+
+ /**
+ * @param string javascript code for client-side onSuccess event.
+ */
+ public function setOnSuccess($javascript)
+ {
+ $this->setFunction('onSuccess', $javascript);
+ }
+
+ /**
+ * @return string javascript code for client-side onFailure event
+ */
+ public function getOnFailure()
+ {
+ return $this->getOption('onFailure');
+ }
+
+ /**
+ * @param string javascript code for client-side onFailure event.
+ */
+ public function setOnFailure($javascript)
+ {
+ $this->setFunction('onFailure', $javascript);
+ }
+
+ public function getCausesValidation()
+ {
+ return $this->getOption('CausesValidation');
+ }
+
+ public function setCausesValidation($value)
+ {
+ $this->getOptions()->add('CausesValidation', TPropertyValue::ensureBoolean($value));
+ }
+
+ public function getValidationGroup()
+ {
+ return $this->getOption('ValidationGroup');
+ }
+
+ public function setValidationGroup($value)
+ {
+ $this->getOptions()->add('ValidationGroup', $value);
+ }
+
+ public function getValidationForm()
+ {
+ return $this->getOption('Form');
+ }
+
+ public function setValidationForm($value)
+ {
+ $this->getOptions()->add('Form', $value);
+ }
+}
+
+?>
diff --git a/framework/Web/UI/ActiveControls/TCallbackResponse.php b/framework/Web/UI/ActiveControls/TCallbackResponse.php
index bda4e916..a05c20c7 100644
--- a/framework/Web/UI/ActiveControls/TCallbackResponse.php
+++ b/framework/Web/UI/ActiveControls/TCallbackResponse.php
@@ -11,8 +11,7 @@
class TCallbackResponse extends THttpResponse
{
- const CALLBACK_DATA_HEADER = 'X-PRADO-DATA';
- const CALLBACK_ACTION_HEADER = 'X-PRADO-ACTIONS';
+
}
diff --git a/framework/Web/UI/TClientScriptManager.php b/framework/Web/UI/TClientScriptManager.php
index 94ef19b6..46203b0b 100644
--- a/framework/Web/UI/TClientScriptManager.php
+++ b/framework/Web/UI/TClientScriptManager.php
@@ -164,6 +164,21 @@ class TClientScriptManager extends TApplicationComponent
}
}
+ public function getCallbackReference($callbackHandler, $options=null)
+ {
+ $options = !is_array($options) ? array() : $options;
+ $class = new TReflectionClass($callbackHandler);
+ if($class->hasMethod('getClientSide'))
+ {
+ $clientSide = $callbackHandler->getClientSide();
+ $options = array_merge($options, $clientSide->getOptions()->toArray());
+ }
+ $optionString = TJavascript::encode($options);
+ $this->registerPradoScriptInternal('ajax');
+ $id = $callbackHandler->getUniqueID();
+ return "new Prado.CallbackRequest('{$id}',{$optionString})";
+ }
+
/**
* Registers postback javascript for a control.
* @param string javascript class responsible for the control being registered for postback
diff --git a/framework/Web/UI/TControl.php b/framework/Web/UI/TControl.php
index 1b5394ba..1db01df6 100644
--- a/framework/Web/UI/TControl.php
+++ b/framework/Web/UI/TControl.php
@@ -1215,9 +1215,6 @@ class TControl extends TApplicationComponent implements IRenderable, IBindable
protected function preRenderRecursive()
{
$this->autoDataBindProperties();
-
- if($this->getEnabled() && $this instanceof IPostBackDataHandler)
- $this->getPage()->registerPostDataLoader($this);
if($this->getVisible(false))
{
@@ -1238,6 +1235,10 @@ class TControl extends TApplicationComponent implements IRenderable, IBindable
}
}
$this->_stage=self::CS_PRERENDERED;
+
+
+ if($this->getEnabled() && $this instanceof IPostBackDataHandler)
+ $this->getPage()->registerPostDataLoader($this);
}
/**
diff --git a/framework/Web/UI/TPage.php b/framework/Web/UI/TPage.php
index 31c80320..c72cdd03 100644
--- a/framework/Web/UI/TPage.php
+++ b/framework/Web/UI/TPage.php
@@ -323,25 +323,6 @@ class TPage extends TTemplateControl
}
/**
- * Gets the callback response handler that permits changing the callback
- * response headers and contents.
- * @return TCallbackResponse callback response handler.
- */
- public function getCallbackResponse()
- {
- return $this->getAdapter()->getCallbackResponseHandler();
- }
-
- /**
- * Set a new callback respond handler.
- * @param TCallbackResponse a different callback response handler.
- */
- public function setCallbackResponse($responder)
- {
- $this->getAdapter()->setCallbackResponseHandler($responder);
- }
-
- /**
* Gets the callback client script handler that allows javascript functions
* to be executed during the callback response.
* @return TCallbackClientScript interface to client-side javascript code.