summaryrefslogtreecommitdiff
path: root/framework
diff options
context:
space:
mode:
authorwei <>2006-09-23 06:40:38 +0000
committerwei <>2006-09-23 06:40:38 +0000
commit6fd29b65290509f55172efccaacb5f91a4a884df (patch)
tree42b15f1a71afec31812fc0961f7fe15b2e4a5dd9 /framework
parenta5467e842316daf6a8a4345740f05a9731167ce1 (diff)
Add TJsonService
Diffstat (limited to 'framework')
-rw-r--r--framework/Web/Javascripts/js/compressed/ajax.js9
-rw-r--r--framework/Web/Javascripts/js/debug/ajax.js14
-rw-r--r--framework/Web/Javascripts/prado/ajax3.js14
-rw-r--r--framework/Web/Services/TJsonService.php171
4 files changed, 201 insertions, 7 deletions
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 @@
+<?php
+/**
+ * TJsonService and TJsonResponse class file.
+ *
+ * @author Wei Zhuo <weizhuo[at]gamil[dot]com>
+ * @link http://www.pradosoft.com/
+ * @copyright Copyright &copy; 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,
+ * <code>
+ * <service id="json" class="System.Services.TJsonService">
+ * <json id="get_article" class="Path.To.JsonResponseClass1" .../>
+ * <json id="register_rating" class="Path.To.JsonResponseClass2" .../>
+ * </service>
+ * </code>
+ * where each JSON response is specified via a &lt;json&gt; element.
+ * Initial property values can be configured in a &lt;json&gt; element.
+ *
+ * To retrieve the JSON content provided by "get_article", use the URL
+ * <code>index.php?json=get_article</code>
+ *
+ * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
+ * @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 <weizhuo[at]gmail[dot]com>
+ * @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