From d255f4d0e332740b3984e21ce3f7a4a4f1968ba3 Mon Sep 17 00:00:00 2001 From: wei <> Date: Tue, 2 May 2006 08:28:17 +0000 Subject: Adding more work on ActiveControls. --- .../Web/UI/ActiveControls/TActivePageAdapter.php | 164 +++++++++++++++++---- 1 file changed, 133 insertions(+), 31 deletions(-) (limited to 'framework/Web/UI/ActiveControls/TActivePageAdapter.php') 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 + * @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; } } -- cgit v1.2.3