From 6fd29b65290509f55172efccaacb5f91a4a884df Mon Sep 17 00:00:00 2001 From: wei <> Date: Sat, 23 Sep 2006 06:40:38 +0000 Subject: Add TJsonService --- framework/Web/Javascripts/js/compressed/ajax.js | 9 +- framework/Web/Javascripts/js/debug/ajax.js | 14 +- framework/Web/Javascripts/prado/ajax3.js | 14 +- framework/Web/Services/TJsonService.php | 171 ++++++++++++++++++++++++ 4 files changed, 201 insertions(+), 7 deletions(-) create mode 100644 framework/Web/Services/TJsonService.php (limited to 'framework') diff --git a/framework/Web/Javascripts/js/compressed/ajax.js b/framework/Web/Javascripts/js/compressed/ajax.js index 1686d86f..79ef1848 100644 --- a/framework/Web/Javascripts/js/compressed/ajax.js +++ b/framework/Web/Javascripts/js/compressed/ajax.js @@ -22,10 +22,13 @@ if(this.responseIsSuccess()){if(this.onComplete) setTimeout(this.onComplete.bind(this),10);}}});Ajax.PeriodicalUpdater=Class.create();Ajax.PeriodicalUpdater.prototype=Object.extend(new Ajax.Base(),{initialize:function(container,url,options){this.setOptions(options);this.onComplete=this.options.onComplete;this.frequency=(this.options.frequency||2);this.decay=(this.options.decay||1);this.updater={};this.container=container;this.url=url;this.start();},start:function(){this.options.onComplete=this.updateComplete.bind(this);this.onTimerEvent();},stop:function(){this.updater.onComplete=undefined;clearTimeout(this.timer);(this.onComplete||Prototype.emptyFunction).apply(this,arguments);},updateComplete:function(request){if(this.options.decay){this.decay=(request.responseText==this.lastText?this.decay*this.options.decay:1);this.lastText=request.responseText;} this.timer=setTimeout(this.onTimerEvent.bind(this),this.decay*this.frequency*1000);},onTimerEvent:function(){this.updater=new Ajax.Updater(this.container,this.url,this.options);}});Object.extend(Ajax.Request.prototype,{respondToReadyState:function(readyState) {var event=Ajax.Request.Events[readyState];var transport=this.transport,json=this.getHeaderData(Prado.CallbackRequest.DATA_HEADER);if(event=='Complete') +{if((this.header('Content-type')||'').match(/^text\/javascript/i)) {try -{Prado.CallbackRequest.updatePageState(this,transport);Ajax.Responders.dispatch('on'+transport.status,this,transport,json);Prado.CallbackRequest.dispatchActions(transport,this.getHeaderData(Prado.CallbackRequest.ACTION_HEADER));(this.options['on'+this.transport.status]||this.options['on'+(this.responseIsSuccess()?'Success':'Failure')]||Prototype.emptyFunction)(this,json);}catch(e){this.dispatchException(e);} -if((this.header('Content-type')||'').match(/^text\/javascript/i)) -this.evalResponse();} +{json=eval('('+transport.responseText+')');}catch(e) +{if(typeof(json)=="string") +json=Prado.CallbackRequest.decode(result);}} +try +{Prado.CallbackRequest.updatePageState(this,transport);Ajax.Responders.dispatch('on'+transport.status,this,transport,json);Prado.CallbackRequest.dispatchActions(transport,this.getHeaderData(Prado.CallbackRequest.ACTION_HEADER));(this.options['on'+this.transport.status]||this.options['on'+(this.responseIsSuccess()?'Success':'Failure')]||Prototype.emptyFunction)(this,json);}catch(e){this.dispatchException(e);}} try{(this.options['on'+event]||Prototype.emptyFunction)(this,json);Ajax.Responders.dispatch('on'+event,this,transport,json);}catch(e){this.dispatchException(e);} if(event=='Complete') this.transport.onreadystatechange=Prototype.emptyFunction;},getHeaderData:function(name) diff --git a/framework/Web/Javascripts/js/debug/ajax.js b/framework/Web/Javascripts/js/debug/ajax.js index 5bd22afa..5acdfb63 100644 --- a/framework/Web/Javascripts/js/debug/ajax.js +++ b/framework/Web/Javascripts/js/debug/ajax.js @@ -302,6 +302,18 @@ Object.extend(Ajax.Request.prototype, if (event == 'Complete') { + if ((this.header('Content-type') || '').match(/^text\/javascript/i)) + { + try + { + json = eval('(' + transport.responseText + ')'); + }catch (e) + { + if(typeof(json) == "string") + json = Prado.CallbackRequest.decode(result); + } + } + try { Prado.CallbackRequest.updatePageState(this,transport); @@ -314,8 +326,6 @@ Object.extend(Ajax.Request.prototype, } catch (e) { this.dispatchException(e); } - if ((this.header('Content-type') || '').match(/^text\/javascript/i)) - this.evalResponse(); } try { diff --git a/framework/Web/Javascripts/prado/ajax3.js b/framework/Web/Javascripts/prado/ajax3.js index 43f159f4..6a20e2b5 100644 --- a/framework/Web/Javascripts/prado/ajax3.js +++ b/framework/Web/Javascripts/prado/ajax3.js @@ -14,6 +14,18 @@ Object.extend(Ajax.Request.prototype, if (event == 'Complete') { + if ((this.header('Content-type') || '').match(/^text\/javascript/i)) + { + try + { + json = eval('(' + transport.responseText + ')'); + }catch (e) + { + if(typeof(json) == "string") + json = Prado.CallbackRequest.decode(result); + } + } + try { Prado.CallbackRequest.updatePageState(this,transport); @@ -26,8 +38,6 @@ Object.extend(Ajax.Request.prototype, } catch (e) { this.dispatchException(e); } - if ((this.header('Content-type') || '').match(/^text\/javascript/i)) - this.evalResponse(); } try { diff --git a/framework/Web/Services/TJsonService.php b/framework/Web/Services/TJsonService.php new file mode 100644 index 00000000..ee5338c8 --- /dev/null +++ b/framework/Web/Services/TJsonService.php @@ -0,0 +1,171 @@ + + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2006 PradoSoft + * @license http://www.pradosoft.com/license/ + * @version $Id$ + * @package System.Web.Services + */ + +/** + * TJsonService class provides to end-users javascript content response in + * JSON format. + * + * TJsonService manages a set of {@link TJsonResponse}, each + * representing specific response with javascript content. + * The service parameter, referring to the ID of the service, specifies + * which javascript content to be provided to end-users. + * + * To use TJsonService, configure it in application configuration as follows, + * + * + * + * + * + * + * where each JSON response is specified via a <json> element. + * Initial property values can be configured in a <json> element. + * + * To retrieve the JSON content provided by "get_article", use the URL + * index.php?json=get_article + * + * @author Wei Zhuo + * @version $Id$ + * @package System.Web.Services + * @since 3.1 + */ +class TJsonService extends TService +{ + /** + * @var array registered services + */ + private $_services=array(); + + /** + * Initializes this module. + * This method is required by the IModule interface. + * @param TXmlElement configuration for this module, can be null + */ + public function init($xml) + { + $this->loadJsonServices($xml); + } + + /** + * Load the service definitions. + * @param TXmlElement configuration for this module, can be null + */ + protected function loadJsonServices($xml) + { + foreach($xml->getElementsByTagName('json') as $config) + { + if(($id=$config->getAttribute('id'))!==null) + $this->_services[$id]=$config; + else + throw new TConfigurationException('jsonservice_id_required'); + } + } + + /** + * Runs the service. + * This method is invoked by application automatically. + */ + public function run() + { + $id=$this->getRequest()->getServiceParameter(); + if(isset($this->_services[$id])) + { + $serviceConfig=$this->_services[$id]; + $properties=$serviceConfig->getAttributes(); + if(($class=$properties->remove('class'))!==null) + { + $service=Prado::createComponent($class); + if($service instanceof TJsonResponse) + $this->createJsonResponse($service,$properties,$serviceConfig); + else + throw new TConfigurationException('jsonservice_response_type_invalid',$id); + } + else + throw new TConfigurationException('jsonservice_class_required',$id); + } + else + throw new THttpException(404,'jsonservice_feed_unknown',$id); + } + + /** + * Renders content provided by TJsonResponse::getJsonContent() as + * javascript in JSON format. + */ + protected function createJsonResponse($service,$properties,$config) + { + // init service properties + foreach($properties as $name=>$value) + $service->setSubproperty($name,$value); + $service->init($config); + + //send content if not null + if(($content=$service->getJsonContent())!==null) + { + $response = $this->getResponse(); + $response->setContentType('text/javascript'); + $response->setCharset('UTF-8'); + $json = Prado::createComponent('System.Web.Javascripts.TJSON'); + + //send content + $response->write($json->encode($content)); + } + } +} + +/** + * TJsonResponse Class + * + * TJsonResponse is the base class for all JSON response provider classes. + * + * Derived classes must implement {@link getJsonContent()} to return + * an object or literals to be converted to JSON format. The response + * will be empty if the returned content is null. + * + * @author Wei Zhuo + * @version $Id$ + * @package System.Web.Services + * @since 3.1 + */ +abstract class TJsonResponse extends TApplicationComponent +{ + private $_id=''; + + /** + * Initializes the feed. + * @param TXmlElement configurations specified in {@link TJsonService}. + */ + public function init($config) + { + } + + /** + * @return string ID of this response + */ + public function getID() + { + return $this->_id; + } + + /** + * @param string ID of this response + */ + public function setID($value) + { + $this->_id=$value; + } + + /** + * @return object json response content, null to supress output. + */ + abstract public function getJsonContent(); +} + +?> \ No newline at end of file -- cgit v1.2.3