summaryrefslogtreecommitdiff
path: root/framework
diff options
context:
space:
mode:
Diffstat (limited to 'framework')
-rw-r--r--framework/DataAccess/SQLMap/Configuration/TSqlMapConditionalTag.php176
-rw-r--r--framework/Exceptions/messages.txt3
-rw-r--r--framework/Web/Javascripts/extended/base.js3
-rw-r--r--framework/Web/Javascripts/js/ajax.js16
-rw-r--r--framework/Web/Javascripts/js/prado.js5
-rw-r--r--framework/Web/Javascripts/prado/activecontrols3.js97
-rw-r--r--framework/Web/Javascripts/prado/ajax3.js2
-rw-r--r--framework/Web/UI/ActiveControls/TCallbackTimer.php142
8 files changed, 438 insertions, 6 deletions
diff --git a/framework/DataAccess/SQLMap/Configuration/TSqlMapConditionalTag.php b/framework/DataAccess/SQLMap/Configuration/TSqlMapConditionalTag.php
new file mode 100644
index 00000000..114bd024
--- /dev/null
+++ b/framework/DataAccess/SQLMap/Configuration/TSqlMapConditionalTag.php
@@ -0,0 +1,176 @@
+<?php
+
+/**
+ * TSqlMapConditionalTag class.
+ *
+ * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
+ * @version : $ Wed Jun 7 07:57:22 EST 2006 $
+ * @package System.DataAccess.SQLMap.Configuration
+ * @since 3.0
+ */
+class TSqlMapConditionalTag extends TComponent
+{
+ public static $ConditionalChecks = array
+ (
+ 'isEqual', 'isNotEqual',
+ 'isGreaterThan', 'isGreaterEqual',
+ 'isLessThan', 'isLessEqual'
+ );
+
+ public static $UnaryChecks = array
+ (
+ 'isNull', 'isNotNull',
+ 'isEmpty', 'isNotEmpty'
+ )
+
+ public static $ParameterChecks = array
+ (
+ 'isPropertyAvailable', 'isPropertyNotAvailable',
+ 'isParameterPresent', 'isParameterNotPresent'
+ )
+
+ private $_tagName;
+ private $_prepend='';
+ private $_property;
+ private $_propertyType = 'string';
+ private $_compareProperty;
+ private $_compareValue;
+
+ public function getTagName(){ return $this->_tagName; }
+ public function setTagName($value){ $this->_tagName = $value; }
+
+ public function getPrepend(){ return $this->_prepend; }
+ public function setPrepend($value){ $this->_prepend = $value; }
+
+ public function getProperty(){ return $this->_property; }
+ public function setProperty($value){ $this->_property = $value; }
+
+ public function getCompareProperty(){ return $this->_compareProperty; }
+ public function setCompareProperty($value){ $this->_compareProperty = $value; }
+
+ public function getCompareValue(){ return $this->_compareValue; }
+ public function setCompareValue($value){ $this->_compareValue = $value; }
+
+ public function getPropertyType(){ return $this->_propertyType; }
+ public function setPropertyType($value){ $this->_propertyType = $value; }
+
+ /**
+ * Evaluates the conditional tag, return true if satisfied, false otherwise.
+ * @param object current conditional tag context.
+ * @param object query parameter object.
+ * @return boolean true if conditions are met, false otherwise.
+ */
+ public function evaluate($context, $parameter)
+ {
+ $value = $this->getPropertyValue($parameter, $this->getProperty());
+ if(in_array($this->getTagName(), self::$UnaryChecks))
+ return $this->evaluateUnary($context, $value);
+ else if(in_array($this->getTagName(), self::$ConditionalChecks))
+ {
+ $comparee = $this->getComparisonValue($parameter)
+ return $this->evaluateConditional($context, $value, $comparee);
+ }
+ else
+ return $this->evaluateParameterCheck($context, $parameter);
+ }
+
+ protected function evaluateUnary($context, $value)
+ {
+ switch($this->getTagName())
+ {
+ case 'isNull':
+ return is_null($value);
+ case 'isNotNull':
+ return !is_null($value);
+ case 'isEmpty':
+ return empty($value);
+ case 'isNotEmpty':
+ return !empty($value);
+ }
+ }
+
+ protected function evaluateConditional($context, $valueA, $valueB)
+ {
+ switch($this->getTagName())
+ {
+ case 'isEqual': return $valueA == $valueB;
+ case 'isNotEqual': return $valueA != $valueB;
+ case 'isGreaterThan': return $valueA > $valueB;
+ case 'isGreaterEqual': return $valueA >= $valueB;
+ case 'isLessThan': return $valueA < $valueB;
+ case 'isLessEqual': return $valueA <= $valueB;
+ }
+ }
+
+ protected function evaluateParameterCheck($context, $parameter)
+ {
+ switch($this->getTagName())
+ {
+ case 'isPropertyAvailable': return TPropertyAccess::has(
+ $parameter, $this->getProperty());
+ case 'isPropertyAvailable': return TPropertyAccess::has(
+ $parameter, $this->getProperty()) == false;
+ case 'isParameterPresent': return !is_null($parameter);
+ case 'isParameterNotPresent': return is_null($parameter);
+ }
+ }
+
+ /**
+ * @param object query parameter object.
+ * @return mixed value for comparison.
+ */
+ protected function getComparisonValue($parameter)
+ {
+ if(strlen($property = $this->getCompareProperty()) > 0
+ && (is_array($parameter) || is_object($parameter)))
+ {
+ $value = TPropertyAccess::get($parameter, $property);
+ }
+ else
+ $value = $this->getCompareValue();
+ return $this->ensureType($value);
+ }
+
+ /**
+ * @param object query parameter object
+ * @param string name of the property in the parameter object used for comparison.
+ * @return mixed value for comparison.
+ */
+ protected function getPropertyValue($parameter, $property)
+ {
+ if(!is_null($property) && !is_null($parameter))
+ {
+ if(is_array($parameter) || is_object($parameter))
+ return $this->ensureType(TPropertyAccess::get($parameter, $property));
+ else
+ return $this->ensureType($parameter);
+ }
+ else
+ return null;
+ }
+
+ /**
+ * @param string property value
+ * @return mixed enforces property value to type given by {@link getPropertyType PropertyType}.
+ */
+ protected function ensureType($value)
+ {
+ switch(strtolower($this->getPropertyType()))
+ {
+ case 'boolean':
+ return TPropertyValue::ensureBoolean($value);
+ case 'integer': case 'int':
+ return TPropertyValue::ensureInteger($value);
+ case 'float': case 'double':
+ return TPropertyValue::ensureFloat($value);
+ case 'array':
+ return TPropertyValue::ensureArray($value);
+ case 'object':
+ return TPropertyValue::ensureObject($value);
+ default:
+ return TPropertyValue::ensureString($value);
+ }
+ }
+}
+
+?> \ No newline at end of file
diff --git a/framework/Exceptions/messages.txt b/framework/Exceptions/messages.txt
index 5fa94202..273d713d 100644
--- a/framework/Exceptions/messages.txt
+++ b/framework/Exceptions/messages.txt
@@ -310,6 +310,9 @@ callback_not_support_no_priority_state_update = Callback request does not suppor
callback_invalid_handler = Invalid callback handler, control {0} must implement ICallbackEventHandler.
callback_invalid_target = Invalid callback target, no such control with ID {0}.
+callback_interval_be_positive = Interval for TCallbackTimer "{0}" must be strictly greater than zero seconds.
+callback_decay_be_not_negative = Decay rate for TCallbackTimer "{0}" must be not negative.
+
xmltransform_xslextension_required = TXmlTransform require the PHP's XSL extension
xmltransform_transformpath_invalid = TransformPath '{0}' is invalid.
xmltransform_documentpath_invalid = DocumentPath '{0}' is invalid.
diff --git a/framework/Web/Javascripts/extended/base.js b/framework/Web/Javascripts/extended/base.js
index d88f82db..cdb7958c 100644
--- a/framework/Web/Javascripts/extended/base.js
+++ b/framework/Web/Javascripts/extended/base.js
@@ -33,7 +33,7 @@ Class.extend = function(base, definition)
Copyright 2006, Dean Edwards
License: http://creativecommons.org/licenses/LGPL/2.1/
*/
-/*
+
var Base = function() {
if (arguments.length) {
if (this == window) { // cast an object to this class
@@ -134,7 +134,6 @@ Base.implement = function(_interface) {
if (_interface instanceof Function) _interface = _interface.prototype;
this.prototype.extend(_interface);
};
-*/
/*
* Signals and Slots for Prototype: Easy custom javascript events
diff --git a/framework/Web/Javascripts/js/ajax.js b/framework/Web/Javascripts/js/ajax.js
index fea7e573..c2fb8f82 100644
--- a/framework/Web/Javascripts/js/ajax.js
+++ b/framework/Web/Javascripts/js/ajax.js
@@ -200,4 +200,18 @@ this.onInit(options);},doCallback:function(event,options)
{var element=Event.findElement(event,'LI');this.index=element.autocompleteIndex;this.selectEntry();this.hide();Event.fireEvent(this.element,"change");},getUpdatedChoices:function()
{options=new Array(this.getToken(),"__TAutComplete_onSuggest__");Prado.Callback(this.options.EventTarget,options,null,this.options);},onComplete:function(request,boundary)
{result=Prado.Element.extractContent(request.responseText,boundary);if(typeof(result)=="string"&&result.length>0)
-this.updateChoices(result);}}); \ No newline at end of file
+this.updateChoices(result);}});Prado.WebUI.TCallbackTimer=Base.extend({count:0,timeout:0,constructor:function(options)
+{this.options=Object.extend({Interval:1,DecayRate:0},options||{})
+this.onComplete=this.options.onComplete;Prado.WebUI.TCallbackTimer.register(this);},startTimer:function()
+{this.options.onComplete=this.onRequestComplete.bind(this);setTimeout(this.onTimerEvent.bind(this),200);},stopTimer:function()
+{(this.onComplete||Prototype.emptyFunction).apply(this,arguments);this.options.onComplete=undefined;clearTimeout(this.timer);this.timer=undefined;this.count=0;},onTimerEvent:function()
+{this.options.params=this.timeout/1000;new Prado.CallbackRequest(this.options.ID,this.options);},onRequestComplete:function()
+{(this.onComplete||Prototype.emptyFunction).apply(this,arguments);this.timer=setTimeout(this.onTimerEvent.bind(this),this.getNewTimeout())},getNewTimeout:function()
+{switch(this.options.DecayType)
+{case'Exponential':t=(Math.exp(this.options.DecayRate*this.count*this.options.Interval))-1;break;case'Linear':t=this.options.DecayRate*this.count*this.options.Interval;break;case'Quadratic':t=this.options.DecayRate*this.count*this.count*this.options.Interval;break;case'Cubic':t=this.options.DecayRate*this.count*this.count*this.count*this.options.Interval;break;default:t=0;}
+this.timeout=(t+this.options.Interval)*1000;this.count++;return parseInt(this.timeout);}},{timers:{},register:function(timer)
+{this.timers[timer.options.ID]=timer;},start:function(id)
+{if(this.timers[id])
+this.timers[id].startTimer();},stop:function(id)
+{if(this.timers[id])
+this.timers[id].stopTimer();}}); \ No newline at end of file
diff --git a/framework/Web/Javascripts/js/prado.js b/framework/Web/Javascripts/js/prado.js
index 38160fee..2cd37002 100644
--- a/framework/Web/Javascripts/js/prado.js
+++ b/framework/Web/Javascripts/js/prado.js
@@ -15,7 +15,10 @@ Function.prototype.bindEvent=function()
Class.extend=function(base,definition)
{var component=Class.create();Object.extend(component.prototype,base.prototype);if(definition)
Object.extend(component.prototype,definition);return component;}
-Signal={throwErrors:true,MT:function(){return true},connect:function(obj1,func1,obj2,func2,options){var options=Object.extend({connectOnce:false},options||{});if(typeof func1!='string'||typeof func2!='string')return;var sigObj=obj1||window;var slotObj=obj2||window;var signame=func1+'__signal_';var slotsname=func1+'__slots_';if(!sigObj[signame]){var slotFunc=function(){var args=arguments;var result=sigObj[signame].apply(sigObj,args);sigObj[slotsname].each(function(slot){try{if(slot&&slot[0]){slot[0][slot[1]].apply(slot[0],args);}}catch(e){if(Signal.throwErrors)throw e;}});return result;};(function(){sigObj[slotsname]=$A([]);sigObj[signame]=sigObj[func1]||Signal.MT;sigObj[func1]=slotFunc;})();}
+var Base=function(){if(arguments.length){if(this==window){Base.prototype.extend.call(arguments[0],arguments.callee.prototype);}else{this.extend(arguments[0]);}}};Base.version="1.0.2";Base.prototype={extend:function(source,value){var extend=Base.prototype.extend;if(arguments.length==2){var ancestor=this[source];if((ancestor instanceof Function)&&(value instanceof Function)&&ancestor.valueOf()!=value.valueOf()&&/\bbase\b/.test(value)){var method=value;value=function(){var previous=this.base;this.base=ancestor;var returnValue=method.apply(this,arguments);this.base=previous;return returnValue;};value.valueOf=function(){return method;};value.toString=function(){return String(method);};}
+return this[source]=value;}else if(source){var _prototype={toSource:null};var _protected=["toString","valueOf"];if(Base._prototyping)_protected[2]="constructor";for(var i=0;(name=_protected[i]);i++){if(source[name]!=_prototype[name]){extend.call(this,name,source[name]);}}
+for(var name in source){if(!_prototype[name]){extend.call(this,name,source[name]);}}}
+return this;},base:function(){}};Base.extend=function(_instance,_static){var extend=Base.prototype.extend;if(!_instance)_instance={};Base._prototyping=true;var _prototype=new this;extend.call(_prototype,_instance);var constructor=_prototype.constructor;_prototype.constructor=this;delete Base._prototyping;var klass=function(){if(!Base._prototyping)constructor.apply(this,arguments);this.constructor=klass;};klass.prototype=_prototype;klass.extend=this.extend;klass.implement=this.implement;klass.toString=function(){return String(constructor);};extend.call(klass,_static);var object=constructor?klass:_prototype;if(object.init instanceof Function)object.init();return object;};Base.implement=function(_interface){if(_interface instanceof Function)_interface=_interface.prototype;this.prototype.extend(_interface);};Signal={throwErrors:true,MT:function(){return true},connect:function(obj1,func1,obj2,func2,options){var options=Object.extend({connectOnce:false},options||{});if(typeof func1!='string'||typeof func2!='string')return;var sigObj=obj1||window;var slotObj=obj2||window;var signame=func1+'__signal_';var slotsname=func1+'__slots_';if(!sigObj[signame]){var slotFunc=function(){var args=arguments;var result=sigObj[signame].apply(sigObj,args);sigObj[slotsname].each(function(slot){try{if(slot&&slot[0]){slot[0][slot[1]].apply(slot[0],args);}}catch(e){if(Signal.throwErrors)throw e;}});return result;};(function(){sigObj[slotsname]=$A([]);sigObj[signame]=sigObj[func1]||Signal.MT;sigObj[func1]=slotFunc;})();}
var con=(sigObj[slotsname].length>0)?(options.connectOnce?!sigObj[slotsname].any(function(slot){return(slot[0]==slotObj&&slot[1]==func2)}):true):true;if(con){sigObj[slotsname].push([slotObj,func2]);}},connectOnce:function(obj1,func1,obj2,func2,options){Signal.connect(obj1,func1,obj2,func2,Object.extend(options||{},{connectOnce:true}))},disconnect:function(obj1,func1,obj2,func2,options){var options=Object.extend({disconnectAll:false},options||{});if(typeof func1!='string'||typeof func2!='string')return;var sigObj=obj1||window;var slotObj=obj2||window;var signame=func1+'__signal_';var slotsname=func1+'__slots_';if(sigObj[slotsname]){if(options.disconnectAll){sigObj[slotsname]=sigObj[slotsname].collect(function(slot){if(slot[0]==slotObj&&slot[1]==func2){slot[0]=null;return null;}else{return slot;}}).compact();}else{var idx=-1;sigObj[slotsname]=sigObj[slotsname].collect(function(slot,index){if(slot[0]==slotObj&&slot[1]==func2&&idx<0){idx=index;slot[0]=null;return null;}else{return slot;}}).compact();}}},disconnectAll:function(obj1,func1,obj2,func2,options){Signal.disconnect(obj1,func1,obj2,func2,Object.extend(options||{},{disconnectAll:true}))}}
Object.extend(String.prototype,{gsub:function(pattern,replacement){var result='',source=this,match;replacement=arguments.callee.prepareReplacement(replacement);while(source.length>0){if(match=source.match(pattern)){result+=source.slice(0,match.index);result+=(replacement(match)||'').toString();source=source.slice(match.index+match[0].length);}else{result+=source,source='';}}
return result;},sub:function(pattern,replacement,count){replacement=this.gsub.prepareReplacement(replacement);count=count===undefined?1:count;return this.gsub(pattern,function(match){if(--count<0)return match[0];return replacement(match);});},scan:function(pattern,iterator){this.gsub(pattern,iterator);return this;},truncate:function(length,truncation){length=length||30;truncation=truncation===undefined?'...':truncation;return this.length>length?this.slice(0,length-truncation.length)+truncation:this;},strip:function(){return this.replace(/^\s+/,'').replace(/\s+$/,'');},stripTags:function(){return this.replace(/<\/?[^>]+>/gi,'');},stripScripts:function(){return this.replace(new RegExp(Prototype.ScriptFragment,'img'),'');},extractScripts:function(){var matchAll=new RegExp(Prototype.ScriptFragment,'img');var matchOne=new RegExp(Prototype.ScriptFragment,'im');return(this.match(matchAll)||[]).map(function(scriptTag){return(scriptTag.match(matchOne)||['',''])[1];});},evalScripts:function(){return this.extractScripts().map(function(script){return eval(script)});},escapeHTML:function(){var div=document.createElement('div');var text=document.createTextNode(this);div.appendChild(text);return div.innerHTML;},unescapeHTML:function(){var div=document.createElement('div');div.innerHTML=this.stripTags();return div.childNodes[0]?div.childNodes[0].nodeValue:'';},toQueryParams:function(){var pairs=this.match(/^\??(.*)$/)[1].split('&');return pairs.inject({},function(params,pairString){var pair=pairString.split('=');params[pair[0]]=pair[1];return params;});},toArray:function(){return this.split('');},camelize:function(){var oStringList=this.split('-');if(oStringList.length==1)return oStringList[0];var camelizedString=this.indexOf('-')==0?oStringList[0].charAt(0).toUpperCase()+oStringList[0].substring(1):oStringList[0];for(var i=1,len=oStringList.length;i<len;i++){var s=oStringList[i];camelizedString+=s.charAt(0).toUpperCase()+s.substring(1);}
diff --git a/framework/Web/Javascripts/prado/activecontrols3.js b/framework/Web/Javascripts/prado/activecontrols3.js
index c0964dcb..50ff39d6 100644
--- a/framework/Web/Javascripts/prado/activecontrols3.js
+++ b/framework/Web/Javascripts/prado/activecontrols3.js
@@ -84,4 +84,99 @@ Prado.WebUI.TAutoComplete = Class.extend(Prado.WebUI.TAutoComplete,
if(typeof(result) == "string" && result.length > 0)
this.updateChoices(result);
}
-}); \ No newline at end of file
+});
+
+/**
+ * Callback Timer class.
+ */
+Prado.WebUI.TCallbackTimer = Base.extend(
+{
+ count : 0,
+ timeout : 0,
+
+ constructor : function(options)
+ {
+ this.options = Object.extend(
+ {
+ Interval : 1,
+ DecayRate : 0
+ }, options || {})
+
+ this.onComplete = this.options.onComplete;
+ Prado.WebUI.TCallbackTimer.register(this);
+ },
+
+ startTimer : function()
+ {
+ this.options.onComplete = this.onRequestComplete.bind(this);
+ setTimeout(this.onTimerEvent.bind(this), 200);
+ },
+
+ stopTimer : function()
+ {
+ (this.onComplete || Prototype.emptyFunction).apply(this, arguments);
+ this.options.onComplete = undefined;
+ clearTimeout(this.timer);
+ this.timer = undefined;
+ this.count = 0;
+ },
+
+ onTimerEvent : function()
+ {
+ this.options.params = this.timeout/1000;
+ new Prado.CallbackRequest(this.options.ID, this.options);
+ },
+
+ onRequestComplete : function()
+ {
+ (this.onComplete || Prototype.emptyFunction).apply(this, arguments);
+ this.timer = setTimeout(this.onTimerEvent.bind(this), this.getNewTimeout())
+ },
+
+ getNewTimeout : function()
+ {
+ switch(this.options.DecayType)
+ {
+ case 'Exponential':
+ t = (Math.exp(this.options.DecayRate*this.count*this.options.Interval))-1;
+ break;
+ case 'Linear':
+ t = this.options.DecayRate*this.count*this.options.Interval;
+ break;
+ case 'Quadratic':
+ t = this.options.DecayRate*this.count*this.count*this.options.Interval;
+ break;
+ case 'Cubic':
+ t = this.options.DecayRate*this.count*this.count*this.count*this.options.Interval;
+ break;
+ default : t = 0;
+ }
+ this.timeout = (t + this.options.Interval)*1000;
+ this.count++;
+ return parseInt(this.timeout);
+ }
+},
+//class methods
+{
+ timers : {},
+
+ register : function(timer)
+ {
+ this.timers[timer.options.ID] = timer;
+ },
+
+ start : function(id)
+ {
+ if(this.timers[id])
+ this.timers[id].startTimer();
+ },
+
+ stop : function(id)
+ {
+ if(this.timers[id])
+ this.timers[id].stopTimer();
+ }
+});
+
+
+
diff --git a/framework/Web/Javascripts/prado/ajax3.js b/framework/Web/Javascripts/prado/ajax3.js
index adf8534a..bae60d89 100644
--- a/framework/Web/Javascripts/prado/ajax3.js
+++ b/framework/Web/Javascripts/prado/ajax3.js
@@ -11,7 +11,7 @@ Object.extend(Ajax.Request.prototype,
{
var event = Ajax.Request.Events[readyState];
var transport = this.transport, json = this.getHeaderData(Prado.CallbackRequest.DATA_HEADER);
-
+
if (event == 'Complete')
{
try
diff --git a/framework/Web/UI/ActiveControls/TCallbackTimer.php b/framework/Web/UI/ActiveControls/TCallbackTimer.php
new file mode 100644
index 00000000..7f1aa692
--- /dev/null
+++ b/framework/Web/UI/ActiveControls/TCallbackTimer.php
@@ -0,0 +1,142 @@
+<?php
+/**
+ * TCallbackTimer 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 $Revision: $ : $
+ * @package System.Web.UI.ActiveControls
+ */
+
+/**
+ * TCallbackTimer class.
+ *
+ * TCallbackTimer sends callback request every {@link setInterval Interval} seconds.
+ * Upon each callback request, the {@link onCallback OnCallback} event is raised.
+ *
+ * The intervals between each request can be increased when the browser is inactive
+ * by changing the {@link setDecayRate DecayRate} to a positive number. The
+ * default decay rate, {@link setDecayType DecayType}, is linear and can be changed to
+ * 'Exponential', 'Linear', 'Quadratic' or 'Cubic'.
+ *
+ * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
+ * @version : $ Mon Jun 19 21:29:42 EST 2006 $
+ * @package System.Web.UI.ActiveControls
+ * @since 3.0
+ */
+class TCallbackTimer extends TCallback
+{
+ /**
+ * @return float seconds between callback requests. Default is 1 second.
+ */
+ public function getInterval()
+ {
+ return $this->getViewState('Interval', 1);
+ }
+
+ /**
+ * @param float seconds between callback requests, must be a positive number, default is 1 second.
+ */
+ public function setInterval($value)
+ {
+ $interval = TPropertyValue::ensureFloat($value);
+ if($interval <= 0)
+ throw new TConfigurationException('callback_interval_be_positive', $this->getID());
+ $this->setViewState('Interval', $interval, 1);
+ }
+
+ /**
+ * Gets the decay rate between callbacks. Default is 0;
+ * @return float decay rate between callbacks.
+ */
+ public function getDecayRate()
+ {
+ return $this->getViewState('Decay', 0);
+ }
+
+ /**
+ * Sets the decay rate between callback. Default is 0;
+ * @param float decay rate between callbacks.
+ */
+ public function setDecayRate($value)
+ {
+ $decay = TPropertyValue::ensureFloat($value);
+ if($decay < 0)
+ throw new TConfigurationException('callback_decay_be_not_negative', $this->getID());
+ $this->setViewState('Decay', $decay);
+ }
+
+ /**
+ * @param string Decay type, allows 'Exponential', 'Linear', 'Quadratic' and 'Cubic'. Default is 'Linear'.
+ */
+ public function setDecayType($value)
+ {
+ $this->setViewState('DecayType', TPropertyValue::ensureEnum($value,
+ 'Exponential', 'Linear', 'Quadratic', 'Cubic'), 'Linear');
+ }
+
+ /**
+ * @return string decay type, default is 'Linear', valid types are 'Exponential', 'Linear', 'Quadratic' and 'Cubic'.
+ */
+ public function getDecayType()
+ {
+ return $this->getViewState('DecayType', 'Linear');
+ }
+
+ /**
+ * Registers the javascript code to start the timer.
+ */
+ public function startTimer()
+ {
+ $id = $this->getClientID();
+ $code = "Prado.WebUI.TCallbackTimer.start('{$id}');";
+ $cs = $this->getPage()->getClientScript();
+ $cs->registerEndScript("{$id}:start", $code);
+ }
+
+ /**
+ * Registers the javascript code to stop the timer.
+ */
+ public function stopTimer()
+ {
+ $id = $this->getClientID();
+ $code = "Prado.WebUI.TCallbackTimer.stop('{$id}');";
+ $cs = $this->getPage()->getClientScript();
+ $cs->registerEndScript("{$id}:stop", $code);
+ }
+
+ /**
+ * @return array list of timer options for client-side.
+ */
+ protected function getTimerOptions()
+ {
+ $options['ID'] = $this->getClientID();
+ $options['Interval'] = $this->getInterval();
+ $options['DecayRate'] = $this->getDecayRate();
+ $options['DecayType'] = $this->getDecayType();
+ return $options;
+ }
+
+ /**
+ * Registers the javascript code for initializing the active control.
+ * @param THtmlWriter the renderer.
+ */
+ public function render($writer)
+ {
+ parent::render($writer);
+ $this->getActiveControl()->registerCallbackClientScript(
+ $this->getClientClassName(), $this->getTimerOptions());
+ }
+
+ /**
+ * @return string corresponding javascript class name for this TActiveButton.
+ */
+ protected function getClientClassName()
+ {
+ return 'Prado.WebUI.TCallbackTimer';
+ }
+}
+
+?> \ No newline at end of file