From 3c03a42d1edb0ec26110ace00f42e156cabff67b Mon Sep 17 00:00:00 2001 From: wei <> Date: Sat, 9 Dec 2006 09:17:22 +0000 Subject: Fixed #433, #384, #439, #477, #435, #422, #401, #359. Add more class docs for sqlmap. --- .../Exceptions/TActiveRecordException.php | 4 +- framework/Data/ActiveRecord/TActiveRecord.php | 18 ++- .../Data/ActiveRecord/TActiveRecordManager.php | 10 +- .../Data/SqlMap/Configuration/TSqlMapStatement.php | 4 +- framework/Data/SqlMap/DataMapper/TLazyLoadList.php | 6 +- .../Data/SqlMap/DataMapper/TPropertyAccess.php | 4 +- framework/Data/SqlMap/DataMapper/TSqlMapCache.php | 10 +- .../Data/SqlMap/DataMapper/TSqlMapException.php | 53 ++++++- .../Data/SqlMap/DataMapper/TSqlMapPagedList.php | 121 ++++++++++----- .../DataMapper/TSqlMapTypeHandlerRegistry.php | 14 +- .../Data/SqlMap/Statements/TCachingStatement.php | 12 +- .../SqlMap/Statements/TDeleteMappedStatement.php | 18 +++ .../SqlMap/Statements/TInsertMappedStatement.php | 18 +++ .../Data/SqlMap/Statements/TMappedStatement.php | 30 +++- .../Data/SqlMap/Statements/TPreparedCommand.php | 19 ++- .../Data/SqlMap/Statements/TPreparedStatement.php | 18 +++ .../Statements/TPreparedStatementFactory.php | 18 +++ .../SqlMap/Statements/TSelectMappedStatement.php | 18 +++ .../Data/SqlMap/Statements/TSimpleDynamicSql.php | 22 ++- framework/Data/SqlMap/Statements/TSqlMapSelect.php | 18 +++ framework/Data/SqlMap/Statements/TStaticSql.php | 18 +++ .../SqlMap/Statements/TUpdateMappedStatement.php | 18 +++ framework/Data/TDbConnection.php | 7 +- framework/Web/Javascripts/js/compressed/ajax.js | 63 ++++---- framework/Web/Javascripts/js/compressed/prado.js | 16 +- framework/Web/Javascripts/js/debug/ajax.js | 169 ++++++++------------- framework/Web/Javascripts/js/debug/prado.js | 23 ++- framework/Web/Javascripts/prado/activecontrols3.js | 56 ++----- framework/Web/Javascripts/prado/ajax3.js | 113 +++++++------- framework/Web/Javascripts/prado/controls.js | 23 ++- framework/Web/THttpResponse.php | 29 +++- framework/Web/THttpResponseAdapter.php | 19 ++- .../Web/UI/ActiveControls/TActiveLinkButton.php | 2 +- .../Web/UI/ActiveControls/TActivePageAdapter.php | 21 ++- framework/Web/UI/ActiveControls/TAutoComplete.php | 32 ++-- .../UI/ActiveControls/TCallbackResponseAdapter.php | 21 +++ .../UI/ActiveControls/TTimeTriggeredCallback.php | 47 +----- .../UI/ActiveControls/TValueTriggeredCallback.php | 26 ++-- framework/Web/UI/WebControls/TTextBox.php | 3 +- framework/interfaces.php | 4 +- 40 files changed, 711 insertions(+), 434 deletions(-) (limited to 'framework') diff --git a/framework/Data/ActiveRecord/Exceptions/TActiveRecordException.php b/framework/Data/ActiveRecord/Exceptions/TActiveRecordException.php index 1df54035..45a575dd 100644 --- a/framework/Data/ActiveRecord/Exceptions/TActiveRecordException.php +++ b/framework/Data/ActiveRecord/Exceptions/TActiveRecordException.php @@ -7,7 +7,7 @@ * @copyright Copyright © 2005-2007 PradoSoft * @license http://www.pradosoft.com/license/ * @version $Id$ - * @package System.Data.ActiveRecord.Exceptions + * @package System.Data.ActiveRecord */ /** @@ -15,7 +15,7 @@ * * @author Wei Zhuo * @version $Id$ - * @package System.Data.ActiveRecord.Exceptions + * @package System.Data.ActiveRecord * @since 3.1 */ class TActiveRecordException extends TException diff --git a/framework/Data/ActiveRecord/TActiveRecord.php b/framework/Data/ActiveRecord/TActiveRecord.php index 4969da09..0855fabf 100644 --- a/framework/Data/ActiveRecord/TActiveRecord.php +++ b/framework/Data/ActiveRecord/TActiveRecord.php @@ -48,7 +48,8 @@ Prado::using('System.Data.ActiveRecord.TActiveRecordCriteria'); * } * * //create a connection and give it to the ActiveRecord manager. - * $conn = new TDbConnection('pgsql:host=localhost;dbname=test', 'dbuser','dbpass'); + * $dsn = 'pgsql:host=localhost;dbname=test'; + * $conn = new TDbConnection($dsn, 'dbuser','dbpass'); * TActiveRecordManager::getInstance()->setDbConnection($conn); * * //load the user record with username (primary key) 'admin'. @@ -190,12 +191,16 @@ abstract class TActiveRecord extends TComponent * For composite primary keys (determined from the table definitions): * * $finder->deleteByPk(array($key1,$key2)); //delete 1 record - * $finder->deleteByPk(array($key1,$key2), array($key3,$key4),...); //delete multiple records - * $finder->deleteByPk(array( array($key1,$key2), array($key3,$key4), .. )); //delete multiple records + * + * //delete multiple records + * $finder->deleteByPk(array($key1,$key2), array($key3,$key4),...); + * + * //delete multiple records + * $finder->deleteByPk(array( array($key1,$key2), array($key3,$key4), .. )); * * - * @param unknown_type $keys - * @return unknown + * @param mixed primary key values. + * @return int number of records deleted. */ public function deleteByPk($keys) { @@ -237,7 +242,8 @@ abstract class TActiveRecord extends TComponent * * Usage: * - * $finder->find('username = :name AND password = :pass', array(':name'=>$name, ':pass'=>$pass)); + * $finder->find('username = :name AND password = :pass', + * array(':name'=>$name, ':pass'=>$pass)); * $finder->find('username = ? AND password = ?', array($name, $pass)); * $finder->find('username = ? AND password = ?', $name, $pass); * //$criteria is of TActiveRecordCriteria diff --git a/framework/Data/ActiveRecord/TActiveRecordManager.php b/framework/Data/ActiveRecord/TActiveRecordManager.php index 12ca993f..883abbf2 100644 --- a/framework/Data/ActiveRecord/TActiveRecordManager.php +++ b/framework/Data/ActiveRecord/TActiveRecordManager.php @@ -19,9 +19,9 @@ Prado::using('System.Data.ActiveRecord.TActiveRecordStateRegistry'); * TActiveRecordManager provides the default DB connection, default object state * registry, default active record gateway, and table meta data inspector. * - * You can provide a different registry by overriding the createObjectStateRegistry() method. - * Similarly, override createRecordGateway() for default gateway and override - * createMetaDataInspector() for meta data inspector. + * You can provide a different registry by overriding the {@link createObjectStateRegistry()} method. + * Similarly, override {@link createRecordGateway()} for default gateway and override + * {@link createMetaDataInspector() }for meta data inspector. * * The default connection can be set as follows: * @@ -30,8 +30,8 @@ Prado::using('System.Data.ActiveRecord.TActiveRecordStateRegistry'); * All new active record created after setting the * {@link DbConnection setDbConnection()} will use that connection. * - * The {@link OnInsert onInsert()}, {@link OnUpdate onUpdate()}, - * {@link OnDelete onDelete()} and {@link onSelect onSelect()} events are raised + * The {@link onInsert()}, {@link onUpdate()}, + * {@link onDelete()} and {@link onSelect()} events are raised * before their respective command are executed. * * @author Wei Zhuo diff --git a/framework/Data/SqlMap/Configuration/TSqlMapStatement.php b/framework/Data/SqlMap/Configuration/TSqlMapStatement.php index 0b4b5781..253d2090 100644 --- a/framework/Data/SqlMap/Configuration/TSqlMapStatement.php +++ b/framework/Data/SqlMap/Configuration/TSqlMapStatement.php @@ -8,7 +8,7 @@ * @copyright Copyright © 2005-2007 PradoSoft * @license http://www.pradosoft.com/license/ * @version $Id$ - * @package System.Data.SqlMap.Configuration. + * @package System.Data.SqlMap.Configuration */ /** @@ -343,7 +343,7 @@ class TSqlMapInsert extends TSqlMapStatement * * @author Wei Zhuo * @version $Id$ - * @package System.Data.SqlMap.Configuration. + * @package System.Data.SqlMap.Configuration * @since 3.1 */ class TSqlMapSelect extends TSqlMapStatement diff --git a/framework/Data/SqlMap/DataMapper/TLazyLoadList.php b/framework/Data/SqlMap/DataMapper/TLazyLoadList.php index 770c217a..c078efeb 100644 --- a/framework/Data/SqlMap/DataMapper/TLazyLoadList.php +++ b/framework/Data/SqlMap/DataMapper/TLazyLoadList.php @@ -7,7 +7,7 @@ * @copyright Copyright © 2005-2007 PradoSoft * @license http://www.pradosoft.com/license/ * @version $Id$ - * @package System.Data.SqlMap.DataMapper + * @package System.Data.SqlMap */ /** @@ -15,7 +15,7 @@ * * @author Wei Zhuo * @version $Id$ - * @package System.Data.SqlMap.DataMapper + * @package System.Data.SqlMap * @since 3.1 */ class TLazyLoadList @@ -108,7 +108,7 @@ class TLazyLoadList * * @author Wei Zhuo * @version $Id$ - * @package System.Data.SqlMap.DataMapper + * @package System.Data.SqlMap * @since 3.1 */ class TObjectProxy diff --git a/framework/Data/SqlMap/DataMapper/TPropertyAccess.php b/framework/Data/SqlMap/DataMapper/TPropertyAccess.php index 901072ea..c89bcb75 100644 --- a/framework/Data/SqlMap/DataMapper/TPropertyAccess.php +++ b/framework/Data/SqlMap/DataMapper/TPropertyAccess.php @@ -7,7 +7,7 @@ * @copyright Copyright © 2005-2007 PradoSoft * @license http://www.pradosoft.com/license/ * @version $Id$ - * @package System.Data.SqlMap.DataMapper + * @package System.Data.SqlMap */ /** @@ -38,7 +38,7 @@ * * @author Wei Zhuo * @version $Id$ - * @package System.Data.SqlMap.DataMapper + * @package System.Data.SqlMap * @since 3.1 */ class TPropertyAccess diff --git a/framework/Data/SqlMap/DataMapper/TSqlMapCache.php b/framework/Data/SqlMap/DataMapper/TSqlMapCache.php index a47ed52a..4a621b6a 100644 --- a/framework/Data/SqlMap/DataMapper/TSqlMapCache.php +++ b/framework/Data/SqlMap/DataMapper/TSqlMapCache.php @@ -7,7 +7,7 @@ * @copyright Copyright © 2005-2007 PradoSoft * @license http://www.pradosoft.com/license/ * @version $Id$ - * @package System.Data.SqlMap.DataMapper + * @package System.Data.SqlMap */ /** @@ -17,7 +17,7 @@ * * @author Wei Zhuo * @version $Id$ - * @package System.Data.SqlMap.DataMapper + * @package System.Data.SqlMap * @since 3.1 */ abstract class TSqlMapCache implements ICache @@ -89,7 +89,7 @@ abstract class TSqlMapCache implements ICache * * @author Wei Zhuo * @version $Id$ - * @package System.Data.SqlMap.DataMapper + * @package System.Data.SqlMap * @since 3.1 */ class TSqlMapFifoCache extends TSqlMapCache @@ -126,7 +126,7 @@ class TSqlMapFifoCache extends TSqlMapCache * * @author Wei Zhuo * @version $Id$ - * @package System.Data.SqlMap.DataMapper + * @package System.Data.SqlMap * @since 3.1 */ class TSqlMapLruCache extends TSqlMapCache @@ -168,7 +168,7 @@ class TSqlMapLruCache extends TSqlMapCache * * @author Wei Zhuo * @version $Id$ - * @package System.Data.SqlMap.DataMapper + * @package System.Data.SqlMap * @since 3.1 */ class TSqlMapApplicationCache implements ICache diff --git a/framework/Data/SqlMap/DataMapper/TSqlMapException.php b/framework/Data/SqlMap/DataMapper/TSqlMapException.php index 52fedb13..76bf7198 100644 --- a/framework/Data/SqlMap/DataMapper/TSqlMapException.php +++ b/framework/Data/SqlMap/DataMapper/TSqlMapException.php @@ -1,13 +1,19 @@ + * @version $Id$ + * @package System.Data.SqlMap + * @since 3.1 + */ class TSqlMapException extends TException { /** - * Constructor. - * @param string error message. This can be a string that is listed - * in the message file. If so, the message in the preferred language - * will be used as the error message. Any rest parameters will be used - * to replace placeholders ({0}, {1}, {2}, etc.) in the message. + * Constructor, similar to the parent constructor. For parameters that + * are of SimpleXmlElement, the tag name and its attribute names and values + * are expanded into a string. */ public function __construct($errorMessage) { @@ -27,6 +33,10 @@ class TSqlMapException extends TException parent::__construct(strtr($errorMessage,$tokens)); } + /** + * @param SimpleXmlElement node + * @return string tag name and attribute names and values. + */ protected function implodeNode($node) { $attributes=array(); @@ -49,21 +59,52 @@ class TSqlMapException extends TException } } +/** + * TSqlMapConfigurationException, raised during configuration file parsing. + * + * @author Wei Zhuo + * @version $Id$ + * @package System.Data.SqlMap + * @since 3.1 + */ class TSqlMapConfigurationException extends TSqlMapException { } +/** + * TSqlMapUndefinedException, raised when mapped statemented are undefined. + * + * @author Wei Zhuo + * @version $Id$ + * @package System.Data.SqlMap + * @since 3.1 + */ class TSqlMapUndefinedException extends TSqlMapException { } +/** + * TSqlMapDuplicateException, raised when a duplicate mapped statement is found. + * + * @author Wei Zhuo + * @version $Id$ + * @package System.Data.SqlMap + * @since 3.1 + */ class TSqlMapDuplicateException extends TSqlMapException { } - +/** + * TInvalidPropertyException, raised when setting or getting an invalid property. + * + * @author Wei Zhuo + * @version $Id$ + * @package System.Data.SqlMap + * @since 3.1 + */ class TInvalidPropertyException extends TSqlMapException { } diff --git a/framework/Data/SqlMap/DataMapper/TSqlMapPagedList.php b/framework/Data/SqlMap/DataMapper/TSqlMapPagedList.php index b15a1d4c..0eb7cc7c 100644 --- a/framework/Data/SqlMap/DataMapper/TSqlMapPagedList.php +++ b/framework/Data/SqlMap/DataMapper/TSqlMapPagedList.php @@ -1,14 +1,31 @@ + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2007 PradoSoft + * @license http://www.pradosoft.com/license/ + * @version $Id$ + * @package System.Data.SqlMap + */ Prado::using('System.Collections.TPagedList'); /** - * TSQLMapPagedList + * TSqlMapPagedList implements a list with paging functionality that retrieves + * data from a SqlMap statement. + * + * The maximum number of records fetched is 3 times the page size. It fetches + * the current, the previous and the next page at a time. This allows the paged + * list to determine if the page is a the begin, the middle or the end of the list. + * + * The paged list does not need to know about the total number of records. * * @author Wei Zhuo * @version $Id$ - * @package System.Web.UI.WebControls - * @since 3.0 + * @package System.Data.SqlMap + * @since 3.1 */ class TSqlMapPagedList extends TPagedList { @@ -18,8 +35,14 @@ class TSqlMapPagedList extends TPagedList private $_nextPageList; private $_delegate=null; - public function __construct(IMappedStatement $statement, - $parameter, $pageSize, $delegate=null) + /** + * Create a new SqlMap paged list. + * @param IMappedStatement SqlMap statement. + * @param mixed query parameters + * @param int page size + * @param mixed delegate for each data row retrieved. + */ + public function __construct(IMappedStatement $statement,$parameter, $pageSize, $delegate=null) { parent::__construct(); parent::setCustomPaging(true); @@ -27,6 +50,12 @@ class TSqlMapPagedList extends TPagedList $this->_delegate=$delegate; } + /** + * Initialize the paged list. + * @param IMappedStatement SqlMap statement. + * @param mixed query parameters + * @param int page size. + */ protected function initialize($statement, $parameter, $pageSize) { $this->_statement = $statement; @@ -36,11 +65,19 @@ class TSqlMapPagedList extends TPagedList $this->gotoPage(0); } + /** + * @throws TSqlMapException custom paging must be enabled. + */ public function setCustomPaging($value) { - throw new TDataMapperException('sqlmap_must_enable_custom_paging'); + throw new TSqlMapException('sqlmap_must_enable_custom_paging'); } + /** + * Fetch data by executing the SqlMap statement. + * @param TPageList current object. + * @param TPagedListFetchDataEventParameter fetch parameters + */ protected function fetchDataFromStatement($sender, $param) { $limit = $this->getOffsetAndLimit($param); @@ -50,22 +87,29 @@ class TSqlMapPagedList extends TPagedList $this->populateData($param, $data); } + /** + * Switches to the next page. + * @return integer|boolean the new page index, false if next page is not availabe. + */ public function nextPage() { - if($this->getIsNextPageAvailable()) - return parent::nextPage(); - else - return false; + return $this->getIsNextPageAvailable() ? parent::nextPage() : false; } + /** + * Switches to the previous page. + * @return integer|boolean the new page index, false if previous page is not availabe. + */ public function previousPage() { - if($this->getIsPreviousPageAvailable()) - return parent::previousPage(); - else - return false; + return $this->getIsPreviousPageAvailable() ? parent::previousPage() : false; } + /** + * Populate the list with the fetched data. + * @param TPagedListFetchDataEventParameter fetch parameters + * @param array fetched data. + */ protected function populateData($param, $data) { $total = $data instanceof TList ? $data->getCount() : count($data); @@ -88,67 +132,72 @@ class TSqlMapPagedList extends TPagedList } else { - $param->setData($this->sublist($data, 0, $pageSize)); - $this->_nextPageList = $this->sublist($data, $pageSize,$total); + $param->setData(array_slice($data, 0, $pageSize)); + $this->_nextPageList = array_slice($data, $pageSize-1,$total); } } else { if($total <= $pageSize) { - $this->_prevPageList = $this->sublist($data, 0, $total); + $this->_prevPageList = array_slice($data, 0, $total); $param->setData(array()); $this->_nextPageList = null; } else if($total <= $pageSize*2) { - $this->_prevPageList = $this->sublist($data, 0, $pageSize); - $param->setData($this->sublist($data, $pageSize, $total)); + $this->_prevPageList = array_slice($data, 0, $pageSize); + $param->setData(array_slice($data, $pageSize, $total)); $this->_nextPageList = null; } else { - $this->_prevPageList = $this->sublist($data, 0, $pageSize); - $param->setData($this->sublist($data, $pageSize, $pageSize*2)); - $this->_nextPageList = $this->sublist($data, $pageSize*2, $total); + $this->_prevPageList = array_slice($data, 0, $pageSize); + $param->setData(array_slice($data, $pageSize, $pageSize)); + $this->_nextPageList = array_slice($data, $pageSize*2, $total-$pageSize*2); } } } - protected function sublist($data, $from, $to) - { - $array = array(); - for($i = $from; $i<$to; $i++) - $array[] = $data[$i]; - return $array; - } - + /** + * Calculate the data fetch offsets and limits. + * @param TPagedListFetchDataEventParameter fetch parameters + * @return array 1st element is the offset, 2nd element is the limit. + */ protected function getOffsetAndLimit($param) { $index = $param->getNewPageIndex(); $pageSize = $this->getPageSize(); - if($index < 1) - return array($index, $pageSize*2); - else - return array(($index-1)*$pageSize, $pageSize*3); + return $index < 1 ? array($index, $pageSize*2) : array(($index-1)*$pageSize, $pageSize*3); } + /** + * @return boolean true if the next page is available, false otherwise. + */ public function getIsNextPageAvailable() { return !is_null($this->_nextPageList); } + /** + * @return boolean true if the previous page is available, false otherwise. + */ public function getIsPreviousPageAvailable() { return !is_null($this->_prevPageList); } + /** + * @return boolean true if is the very last page, false otherwise. + */ public function getIsLastPage() { - return is_null($this->_nextPageList) - || $this->_nextPageList->getCount() < 1; + return is_null($this->_nextPageList) || $this->_nextPageList->getCount() < 1; } + /** + * @return boolean true if is not first nor last page, false otherwise. + */ public function getIsMiddlePage() { return !($this->getIsFirstPage() || $this->getIsLastPage()); diff --git a/framework/Data/SqlMap/DataMapper/TSqlMapTypeHandlerRegistry.php b/framework/Data/SqlMap/DataMapper/TSqlMapTypeHandlerRegistry.php index c26c0401..d58a7e3c 100644 --- a/framework/Data/SqlMap/DataMapper/TSqlMapTypeHandlerRegistry.php +++ b/framework/Data/SqlMap/DataMapper/TSqlMapTypeHandlerRegistry.php @@ -1,4 +1,14 @@ + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2007 PradoSoft + * @license http://www.pradosoft.com/license/ + * @version $Id$ + * @package System.Data.SqlMap + */ /** * TTypeHandlerFactory provides type handler classes to convert database field type @@ -6,7 +16,7 @@ * * @author Wei Zhuo * @version $Id$ - * @package System.Data.SqlMap.DataMapper + * @package System.Data.SqlMap * @since 3.1 */ class TSqlMapTypeHandlerRegistry @@ -112,7 +122,7 @@ class TSqlMapTypeHandlerRegistry * * @author Wei Zhuo * @version $Id$ - * @package System.Data.SqlMap.DataMapper + * @package System.Data.SqlMap * @since 3.1 */ abstract class TSqlMapTypeHandler extends TComponent diff --git a/framework/Data/SqlMap/Statements/TCachingStatement.php b/framework/Data/SqlMap/Statements/TCachingStatement.php index 0bcc5291..7d0c0824 100644 --- a/framework/Data/SqlMap/Statements/TCachingStatement.php +++ b/framework/Data/SqlMap/Statements/TCachingStatement.php @@ -1,7 +1,17 @@ + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2007 PradoSoft + * @license http://www.pradosoft.com/license/ + * @version $Id$ + * @package System.Data.SqlMap.Statements + */ + +/** + * TCacheingStatement class. * * @author Wei Zhuo * @version $Id$ diff --git a/framework/Data/SqlMap/Statements/TDeleteMappedStatement.php b/framework/Data/SqlMap/Statements/TDeleteMappedStatement.php index 9a1c8fae..1107a254 100644 --- a/framework/Data/SqlMap/Statements/TDeleteMappedStatement.php +++ b/framework/Data/SqlMap/Statements/TDeleteMappedStatement.php @@ -1,5 +1,23 @@ + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2007 PradoSoft + * @license http://www.pradosoft.com/license/ + * @version $Id$ + * @package System.Data.SqlMap.Statements + */ +/** + * TDeleteMappedStatement class. + * + * @author Wei Zhuo + * @version $Id$ + * @package System.Data.SqlMap.Statements + * @since 3.1 + */ class TDeleteMappedStatement extends TUpdateMappedStatement { } diff --git a/framework/Data/SqlMap/Statements/TInsertMappedStatement.php b/framework/Data/SqlMap/Statements/TInsertMappedStatement.php index 46814aee..50386193 100644 --- a/framework/Data/SqlMap/Statements/TInsertMappedStatement.php +++ b/framework/Data/SqlMap/Statements/TInsertMappedStatement.php @@ -1,5 +1,23 @@ + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2007 PradoSoft + * @license http://www.pradosoft.com/license/ + * @version $Id$ + * @package System.Data.SqlMap.Statements + */ +/** + * TInsertMappedStatement class. + * + * @author Wei Zhuo + * @version $Id$ + * @package System.Data.SqlMap.Statements + * @since 3.1 + */ class TInsertMappedStatement extends TMappedStatement { public function executeQueryForMap($connection, $parameter, diff --git a/framework/Data/SqlMap/Statements/TMappedStatement.php b/framework/Data/SqlMap/Statements/TMappedStatement.php index 6bd4eb47..0989b6ff 100644 --- a/framework/Data/SqlMap/Statements/TMappedStatement.php +++ b/framework/Data/SqlMap/Statements/TMappedStatement.php @@ -7,7 +7,7 @@ * @copyright Copyright © 2005-2007 PradoSoft * @license http://www.pradosoft.com/license/ * @version $Id$ - * @package System.Data.SQLMap.Statements + * @package System.Data.SqlMap.Statements */ /** @@ -18,7 +18,7 @@ * * @author Wei Zhuo * @version $Id$ - * @package System.DataAccess.SQLMap.Statements + * @package System.Data.SqlMap.Statements * @since 3.0 */ class TMappedStatement extends TComponent implements IMappedStatement @@ -912,6 +912,14 @@ class TMappedStatement extends TComponent implements IMappedStatement } } +/** + * TPostSelectBinding class. + * + * @author Wei Zhuo + * @version $Id$ + * @package System.Data.SqlMap.Statements + * @since 3.1 + */ class TPostSelectBinding { private $_statement=null; @@ -945,7 +953,7 @@ class TPostSelectBinding * * @author Wei Zhuo * @version $Id$ - * @package System.DataAccess.SQLMap.Statements + * @package System.Data.SqlMap.Statements * @since 3.1 */ class TSQLMapObjectCollectionTree @@ -1119,6 +1127,14 @@ class TSQLMapObjectCollectionTree } } +/** + * TResultSetListItemParameter class + * + * @author Wei Zhuo + * @version $Id$ + * @package System.Data.SqlMap.Statements + * @since 3.1 + */ class TResultSetListItemParameter extends TComponent { private $_resultObject; @@ -1148,6 +1164,14 @@ class TResultSetListItemParameter extends TComponent } } +/** + * TResultSetMapItemParameter class. + * + * @author Wei Zhuo + * @version $Id$ + * @package System.Data.SqlMap.Statements + * @since 3.1 + */ class TResultSetMapItemParameter extends TComponent { private $_key; diff --git a/framework/Data/SqlMap/Statements/TPreparedCommand.php b/framework/Data/SqlMap/Statements/TPreparedCommand.php index 5a8041ae..7bb68c79 100644 --- a/framework/Data/SqlMap/Statements/TPreparedCommand.php +++ b/framework/Data/SqlMap/Statements/TPreparedCommand.php @@ -1,8 +1,25 @@ + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2007 PradoSoft + * @license http://www.pradosoft.com/license/ + * @version $Id$ + * @package System.Data.SqlMap.Statements + */ +/** + * TPreparedCommand class. + * + * @author Wei Zhuo + * @version $Id$ + * @package System.Data.SqlMap.Statements + * @since 3.1 + */ class TPreparedCommand { - public function create(TSqlMapManager $manager, $connection, $statement, $parameterObject) { $prepared = $statement->getSQLText()->getPreparedStatement($parameterObject); diff --git a/framework/Data/SqlMap/Statements/TPreparedStatement.php b/framework/Data/SqlMap/Statements/TPreparedStatement.php index e534f532..2943b761 100644 --- a/framework/Data/SqlMap/Statements/TPreparedStatement.php +++ b/framework/Data/SqlMap/Statements/TPreparedStatement.php @@ -1,5 +1,23 @@ + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2007 PradoSoft + * @license http://www.pradosoft.com/license/ + * @version $Id$ + * @package System.Data.SqlMap.Statements + */ +/** + * TpreparedStatement class. + * + * @author Wei Zhuo + * @version $Id$ + * @package System.Data.SqlMap.Statements + * @since 3.1 + */ class TPreparedStatement extends TComponent { private $_sqlString=''; diff --git a/framework/Data/SqlMap/Statements/TPreparedStatementFactory.php b/framework/Data/SqlMap/Statements/TPreparedStatementFactory.php index 52461983..122acf45 100644 --- a/framework/Data/SqlMap/Statements/TPreparedStatementFactory.php +++ b/framework/Data/SqlMap/Statements/TPreparedStatementFactory.php @@ -1,5 +1,23 @@ + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2007 PradoSoft + * @license http://www.pradosoft.com/license/ + * @version $Id$ + * @package System.Data.SqlMap.Statements + */ +/** + * TPreparedStatementFactory class. + * + * @author Wei Zhuo + * @version $Id$ + * @package System.Data.SqlMap.Statements + * @since 3.1 + */ class TPreparedStatementFactory { private $_statement; diff --git a/framework/Data/SqlMap/Statements/TSelectMappedStatement.php b/framework/Data/SqlMap/Statements/TSelectMappedStatement.php index b6f179c0..c2e18e9e 100644 --- a/framework/Data/SqlMap/Statements/TSelectMappedStatement.php +++ b/framework/Data/SqlMap/Statements/TSelectMappedStatement.php @@ -1,5 +1,23 @@ + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2007 PradoSoft + * @license http://www.pradosoft.com/license/ + * @version $Id$ + * @package System.Data.SqlMap.Statements + */ +/** + * TSelectMappedStatment class. + * + * @author Wei Zhuo + * @version $Id$ + * @package System.Data.SqlMap.Statements + * @since 3.1 + */ class TSelectMappedStatement extends TMappedStatement { public function executeInsert($connection, $parameter) diff --git a/framework/Data/SqlMap/Statements/TSimpleDynamicSql.php b/framework/Data/SqlMap/Statements/TSimpleDynamicSql.php index 1230b4f7..8c203370 100644 --- a/framework/Data/SqlMap/Statements/TSimpleDynamicSql.php +++ b/framework/Data/SqlMap/Statements/TSimpleDynamicSql.php @@ -1,9 +1,27 @@ + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2007 PradoSoft + * @license http://www.pradosoft.com/license/ + * @version $Id$ + * @package System.Data.SqlMap.Statements + */ +/** + * TSimpleDynamicSql class. + * + * @author Wei Zhuo + * @version $Id$ + * @package System.Data.SqlMap.Statements + * @since 3.1 + */ class TSimpleDynamicSql extends TStaticSql { private $_mappings=array(); - + public function __construct($mappings) { $this->_mappings = $mappings; @@ -16,7 +34,7 @@ class TSimpleDynamicSql extends TStaticSql $this->mapDynamicParameter($statement, $parameter); return $statement; } - + protected function mapDynamicParameter($statement, $parameter) { $sql = $statement->getPreparedSql(); diff --git a/framework/Data/SqlMap/Statements/TSqlMapSelect.php b/framework/Data/SqlMap/Statements/TSqlMapSelect.php index b33bc27e..258eae3f 100644 --- a/framework/Data/SqlMap/Statements/TSqlMapSelect.php +++ b/framework/Data/SqlMap/Statements/TSqlMapSelect.php @@ -1,5 +1,23 @@ + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2007 PradoSoft + * @license http://www.pradosoft.com/license/ + * @version $Id$ + * @package System.Data.SqlMap.Statements + */ +/** + * TSqlMapSelect class file. + * + * @author Wei Zhuo + * @version $Id$ + * @package System.Data.SqlMap.Statements + * @since 3.1 + */ class TSqlMapSelect extends TSqlMapStatement { private $_generate; diff --git a/framework/Data/SqlMap/Statements/TStaticSql.php b/framework/Data/SqlMap/Statements/TStaticSql.php index b99b86ed..f8056028 100644 --- a/framework/Data/SqlMap/Statements/TStaticSql.php +++ b/framework/Data/SqlMap/Statements/TStaticSql.php @@ -1,5 +1,23 @@ + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2007 PradoSoft + * @license http://www.pradosoft.com/license/ + * @version $Id$ + * @package System.Data.SqlMap.Statements + */ +/** + * TStaticSql class. + * + * @author Wei Zhuo + * @version $Id$ + * @package System.Data.SqlMap.Statements + * @since 3.1 + */ class TStaticSql extends TComponent { private $_preparedStatement; diff --git a/framework/Data/SqlMap/Statements/TUpdateMappedStatement.php b/framework/Data/SqlMap/Statements/TUpdateMappedStatement.php index 46d27778..28f6fc4c 100644 --- a/framework/Data/SqlMap/Statements/TUpdateMappedStatement.php +++ b/framework/Data/SqlMap/Statements/TUpdateMappedStatement.php @@ -1,5 +1,23 @@ + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2007 PradoSoft + * @license http://www.pradosoft.com/license/ + * @version $Id$ + * @package System.Data.SqlMap.Statements + */ +/** + * TUpdateMappedStatement class. + * + * @author Wei Zhuo + * @version $Id$ + * @package System.Data.SqlMap.Statements + * @since 3.1 + */ class TUpdateMappedStatement extends TMappedStatement { public function executeInsert($connection, $parameter) diff --git a/framework/Data/TDbConnection.php b/framework/Data/TDbConnection.php index 33bb585e..be61e0a4 100644 --- a/framework/Data/TDbConnection.php +++ b/framework/Data/TDbConnection.php @@ -40,7 +40,9 @@ Prado::using('System.Data.TDbCommand'); * $command->execute(); // a non-query SQL statement execution * // or execute an SQL query and fetch the result set * $reader=$command->query(); - * foreach($reader as $row) ... // each $row is an array representing a row of data + * + * // each $row is an array representing a row of data + * foreach($reader as $row) ... * * * One can do prepared SQL execution and bind parameters to the prepared SQL: @@ -154,7 +156,8 @@ class TDbConnection extends TComponent { try { - $this->_pdo=new PDO($this->getConnectionString(),$this->getUsername(),$this->getPassword(),$this->_attributes); + $this->_pdo=new PDO($this->getConnectionString(),$this->getUsername(), + $this->getPassword(),$this->_attributes); $this->_pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $this->_active=true; } diff --git a/framework/Web/Javascripts/js/compressed/ajax.js b/framework/Web/Javascripts/js/compressed/ajax.js index 4b260ab3..593b4c15 100644 --- a/framework/Web/Javascripts/js/compressed/ajax.js +++ b/framework/Web/Javascripts/js/compressed/ajax.js @@ -22,7 +22,8 @@ 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)) +{if(this.header('X-PRADO-REDIRECT')) +document.location.href=this.header('X-PRADO-REDIRECT');if((this.header('Content-type')||'').match(/^text\/javascript/i)) {try {json=eval('('+transport.responseText+')');}catch(e) {if(typeof(json)=="string") @@ -36,7 +37,7 @@ this.transport.onreadystatechange=Prototype.emptyFunction;},getHeaderData:functi {var json=this.header(name);return eval('('+json+')');} catch(e) {if(typeof(json)=="string") -return Prado.CallbackRequest.decode(json);}}});Prado.CallbackRequest=Class.create();Object.extend(Prado.CallbackRequest,{FIELD_CALLBACK_TARGET:'PRADO_CALLBACK_TARGET',FIELD_CALLBACK_PARAMETER:'PRADO_CALLBACK_PARAMETER',FIELD_CALLBACK_PAGESTATE:'PRADO_PAGESTATE',FIELD_POSTBACK_TARGET:'PRADO_POSTBACK_TARGET',FIELD_POSTBACK_PARAMETER:'PRADO_POSTBACK_PARAMETER',PostDataLoaders:[],DATA_HEADER:'X-PRADO-DATA',ACTION_HEADER:'X-PRADO-ACTIONS',ERROR_HEADER:'X-PRADO-ERROR',PAGESTATE_HEADER:'X-PRADO-PAGESTATE',currentRequest:null,requestQueue:[],addPostLoaders:function(ids) +return Prado.CallbackRequest.decode(json);}}});Prado.CallbackRequest=Class.create();Object.extend(Prado.CallbackRequest,{FIELD_CALLBACK_TARGET:'PRADO_CALLBACK_TARGET',FIELD_CALLBACK_PARAMETER:'PRADO_CALLBACK_PARAMETER',FIELD_CALLBACK_PAGESTATE:'PRADO_PAGESTATE',FIELD_POSTBACK_TARGET:'PRADO_POSTBACK_TARGET',FIELD_POSTBACK_PARAMETER:'PRADO_POSTBACK_PARAMETER',PostDataLoaders:[],DATA_HEADER:'X-PRADO-DATA',ACTION_HEADER:'X-PRADO-ACTIONS',ERROR_HEADER:'X-PRADO-ERROR',PAGESTATE_HEADER:'X-PRADO-PAGESTATE',requestQueue:[],addPostLoaders:function(ids) {var self=Prado.CallbackRequest;self.PostDataLoaders=self.PostDataLoaders.concat(ids);var list=[];self.PostDataLoaders.each(function(id) {if(list.indexOf(id)<0) list.push(id);});self.PostDataLoaders=list;},dispatchActions:function(transport,actions) @@ -65,35 +66,28 @@ msg+=e.version+" "+e.time+"\n";return msg;}},encode:function(data) {return Prado.JSON.stringify(data);},decode:function(data) {if(typeof(data)=="string"&&data.trim().length>0) return Prado.JSON.parse(data);else -return null;},dispatchPriorityRequest:function(callback) -{var self=Prado.CallbackRequest;callback.request=new Ajax.Request(callback.url,callback.options);callback.timeout=setTimeout(function() -{self.abortCurrentRequest();},callback.options.RequestTimeOut);self.currentRequest=callback;return true;},dispatchNormalRequest:function(callback) -{new Ajax.Request(callback.url,callback.options);return true;},abortCurrentRequest:function() -{var self=Prado.CallbackRequest;var inProgress=self.currentRequest;if(inProgress) -{clearTimeout(inProgress.timeout);self.currentRequest=null;if(inProgress.request.transport.readyState<4) -inProgress.request.transport.abort();return self.dispatchQueue();} -else -return self.dispatchQueue();},updatePageState:function(request,transport) +return null;},dispatchNormalRequest:function(callback) +{new Ajax.Request(callback.url,callback.options);return true;},tryNextRequest:function() +{var self=Prado.CallbackRequest;if(typeof(self.currentRequest)=='undefined'||self.currentRequest==null) +{if(self.requestQueue.length>0) +return self.dispatchQueue();}},updatePageState:function(request,transport) {var self=Prado.CallbackRequest;var pagestate=$(self.FIELD_CALLBACK_PAGESTATE);var enabled=request.options.EnablePageStateUpdate&&request.options.HasPriority;var aborted=self.currentRequest==null;if(enabled&&!aborted&&pagestate) {var data=request.header(self.PAGESTATE_HEADER);if(typeof(data)=="string"&&data.length>0) pagestate.value=data;else {if(typeof(Logger)!="undefined") -Logger.warn("Missing page state:"+data);return false;}} -return true;},enqueue:function(callback) -{var self=Prado.CallbackRequest;if(self.currentRequest==null) -self.dispatchPriorityRequest(callback);else -self.requestQueue.push(callback);},dispatchQueue:function() -{var self=Prado.CallbackRequest;if(self.requestQueue.length>0) -{var callback=self.requestQueue.shift();return self.dispatchPriorityRequest(callback);} -return false;},abortRequest:function(id) -{var self=Prado.CallbackRequest;if(self.currentRequest!=null&&self.currentRequest.id==id) -self.abortCurrentRequest();else -{var queque=[];self.requestQueue.each(function(callback) -{if(callback.id!=id) -queque.push(callback);});self.requestQueue=queque;}}}) +Logger.warn("Missing page state:"+data);self.endCurrentRequest();return false;}} +self.endCurrentRequest();return true;},enqueue:function(callback) +{var self=Prado.CallbackRequest;self.requestQueue.push(callback);self.tryNextRequest();},dispatchQueue:function() +{var self=Prado.CallbackRequest;var callback=self.requestQueue.shift();self.currentRequest=callback;callback.options.postBody=callback._getPostData(),callback.request=new Ajax.Request(callback.url,callback.options);callback.timeout=setTimeout(function() +{self.abortRequest(callback.id);},callback.options.RequestTimeOut);},endCurrentRequest:function() +{var self=Prado.CallbackRequest;clearTimeout(self.currentRequest.timeout);self.currentRequest=null;},abortRequest:function(id) +{var self=Prado.CallbackRequest;if(typeof(self.currentRequest)!='undefined'&&self.currentRequest!=null&&self.currentRequest.id==id) +{var request=self.currentRequest.request;if(request.transport.readyState<4) +request.transport.abort();self.endCurrentRequest();} +self.tryNextRequest();}}) Ajax.Responders.register({onComplete:function(request) {if(request.options.HasPriority) -Prado.CallbackRequest.abortCurrentRequest();}});Event.OnLoad(function() +Prado.CallbackRequest.tryNextRequest();}});Event.OnLoad(function() {if(typeof Logger!="undefined") Ajax.Responders.register(Prado.CallbackRequest.Exception);});Prado.CallbackRequest.prototype={url:window.location.href,options:{},id:null,request:null,Enabled:true,initialize:function(id,options) {this.id=id;this.options=Object.extend({RequestTimeOut:30000,EnablePageStateUpdate:true,HasPriority:true,CausesValidation:true,ValidationGroup:null,PostInputs:true},options||{});},setCallbackParameter:function(value) @@ -106,7 +100,7 @@ Ajax.Responders.register(Prado.CallbackRequest.Exception);});Prado.CallbackReque {this.options['ValidationGroup']=group;},getValidationGroup:function() {return this.options['ValidationGroup'];},dispatch:function() {if(typeof tinyMCE!="undefined") -tinyMCE.triggerSave();Object.extend(this.options,{postBody:this._getPostData(),parameters:''});if(this.options.CausesValidation&&typeof(Prado.Validation)!="undefined") +tinyMCE.triggerSave();Object.extend(this.options,{parameters:''});if(this.options.CausesValidation&&typeof(Prado.Validation)!="undefined") {var form=this.options.Form||Prado.Validation.getForm();if(Prado.Validation.validate(form,this.options.ValidationGroup,this)==false) return false;} if(this.options.onPreDispatch) @@ -241,16 +235,13 @@ 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() {var options=new Array(this.getToken(),"__TAutoComplete_onSuggest__");Prado.Callback(this.options.EventTarget,options,null,this.options);},onComplete:function(request,boundary) {var result=Prado.Element.extractContent(request.transport.responseText,boundary);if(typeof(result)=="string"&&result.length>0) -this.updateChoices(result);}});Prado.WebUI.TTimeTriggeredCallback=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.TTimeTriggeredCallback.register(this);},startTimer:function() -{this.options.onComplete=this.onRequestComplete.bind(this);this.timer=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;var request=new Prado.CallbackRequest(this.options.EventTarget,this.options);request.dispatch();},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.updateChoices(result);}});Prado.WebUI.TTimeTriggeredCallback=Base.extend({constructor:function(options) +{this.options=Object.extend({Interval:1},options||{});Prado.WebUI.TTimeTriggeredCallback.register(this);},startTimer:function() +{setTimeout(this.onTimerEvent.bind(this),100);if(typeof(this.timer)=='undefined'||this.timer==null) +this.timer=setInterval(this.onTimerEvent.bind(this),this.options.Interval*1000);},stopTimer:function() +{if(typeof(this.timer)!='undefined') +{clearInterval(this.timer);this.timer=null;}},onTimerEvent:function() +{var request=new Prado.CallbackRequest(this.options.EventTarget,this.options);request.dispatch();}},{timers:{},register:function(timer) {Prado.WebUI.TTimeTriggeredCallback.timers[timer.options.ID]=timer;},start:function(id) {Prado.WebUI.TTimeTriggeredCallback.timers[id].startTimer();},stop:function(id) {Prado.WebUI.TTimeTriggeredCallback.timers[id].stopTimer();}});Prado.WebUI.ActiveListControl=Base.extend({constructor:function(options) diff --git a/framework/Web/Javascripts/js/compressed/prado.js b/framework/Web/Javascripts/js/compressed/prado.js index 9f8cdb19..9e0b9ba8 100644 --- a/framework/Web/Javascripts/js/compressed/prado.js +++ b/framework/Web/Javascripts/js/compressed/prado.js @@ -371,11 +371,17 @@ else {y_input=INPUT({type:'hidden',name:id+'_y','id':id+'_y',value:y});this.element.parentNode.appendChild(y_input);}}});Prado.WebUI.TRadioButton=Class.extend(Prado.WebUI.PostBackControl);Prado.WebUI.TRadioButton.prototype.onRadioButtonInitialize=Prado.WebUI.TRadioButton.prototype.initialize;Object.extend(Prado.WebUI.TRadioButton.prototype,{initialize:function(options) {this.element=$(options['ID']);if(!this.element.checked) this.onRadioButtonInitialize(options);}});Prado.WebUI.TTextBox=Class.extend(Prado.WebUI.PostBackControl,{onInit:function(options) -{if(options['TextMode']!='MultiLine') -Event.observe(this.element,"keydown",this.handleReturnKey.bind(this));Event.observe(this.element,"change",Prado.PostBack.bindEvent(this,options));},handleReturnKey:function(e) +{this.options=options;if(options['TextMode']!='MultiLine') +Event.observe(this.element,"keydown",this.handleReturnKey.bind(this));if(this.options['AutoPostBack']==true) +Event.observe(this.element,"change",Prado.PostBack.bindEvent(this,options));},handleReturnKey:function(e) {if(Event.keyCode(e)==Event.KEY_RETURN) {var target=Event.element(e);if(target) -{Event.fireEvent(target,"change");Event.stop(e);}}}});Prado.WebUI.TListControl=Class.extend(Prado.WebUI.PostBackControl,{onInit:function(options) +{if(this.options['AutoPostBack']==true) +{Event.fireEvent(target,"change");Event.stop(e);} +else +{if(this.options['CausesValidation']&&typeof(Prado.Validation)!="undefined") +{if(!Prado.Validation.validate(this.options['FormID'],this.options['ValidationGroup'],$(this.options['ID']))) +return Event.stop(e);}}}}}});Prado.WebUI.TListControl=Class.extend(Prado.WebUI.PostBackControl,{onInit:function(options) {Event.observe(this.element,"change",Prado.PostBack.bindEvent(this,options));}});Prado.WebUI.TListBox=Class.extend(Prado.WebUI.TListControl);Prado.WebUI.TDropDownList=Class.extend(Prado.WebUI.TListControl);Prado.WebUI.DefaultButton=Class.create();Prado.WebUI.DefaultButton.prototype={initialize:function(options) {this.options=options;this._event=this.triggerEvent.bindEvent(this);Event.observe(options['Panel'],'keydown',this._event);},triggerEvent:function(ev,target) {var enterPressed=Event.keyCode(ev)==Event.KEY_RETURN;var isTextArea=Event.element(ev).tagName.toLowerCase()=="textarea";if(enterPressed&&!isTextArea) @@ -392,6 +398,6 @@ window.clipboardData.setData("Text",text);},hover:function(obj) {obj.parentNode.className="copycode copycode_hover";},out:function(obj) {obj.parentNode.className="copycode";}});Prado.WebUI.TCheckBoxList=Base.extend({constructor:function(options) {for(var i=0;i 0) + return self.dispatchQueue(); + //else + //Logger.warn('empty queque'); } - else - return self.dispatchQueue(); +// else + // Logger.warn('current request ' + self.currentRequest.id); }, /** @@ -622,51 +598,66 @@ Object.extend(Prado.CallbackRequest, { if(typeof(Logger) != "undefined") Logger.warn("Missing page state:"+data); +// Logger.warn('## bad state: setting current request to null'); + self.endCurrentRequest(); + //self.tryNextRequest(); return false; } } + self.endCurrentRequest(); + // Logger.warn('## state updated: setting current request to null'); + // self.tryNextRequest(); return true; }, enqueue : function(callback) { var self = Prado.CallbackRequest; - if(self.currentRequest==null) - self.dispatchPriorityRequest(callback); - else - self.requestQueue.push(callback); - //Logger.info("current queque length="+self.requestQueue.length); + self.requestQueue.push(callback); + //Logger.warn("equeued "+callback.id+", current queque length="+self.requestQueue.length); + self.tryNextRequest(); }, dispatchQueue : function() { var self = Prado.CallbackRequest; - //Logger.info("dispatching queque, length="+self.requestQueue.length+" request="+self.currentRequest); - if(self.requestQueue.length > 0) + //Logger.warn("dispatching queque, length="+self.requestQueue.length+" request="+self.currentRequest); + var callback = self.requestQueue.shift(); + self.currentRequest = callback; + + //get data + callback.options.postBody = callback._getPostData(), + + callback.request = new Ajax.Request(callback.url, callback.options); + callback.timeout = setTimeout(function() { - var callback = self.requestQueue.shift(); - //Logger.info("do dispatch request"); - return self.dispatchPriorityRequest(callback); - } - return false; + //Logger.warn("priority timeout"); + self.abortRequest(callback.id); + },callback.options.RequestTimeOut); + //Logger.debug("dispatched "+self.currentRequest.id + " ...") + }, + + endCurrentRequest : function() + { + var self = Prado.CallbackRequest; + clearTimeout(self.currentRequest.timeout); + self.currentRequest=null; }, abortRequest : function(id) { - //Logger.info("abort id="+id); + //Logger.warn("abort id="+id); var self = Prado.CallbackRequest; - if(self.currentRequest != null && self.currentRequest.id == id) - self.abortCurrentRequest(); - else + if(typeof(self.currentRequest) != 'undefined' + && self.currentRequest != null && self.currentRequest.id == id) { - var queque = []; - self.requestQueue.each(function(callback) - { - if(callback.id != id) - queque.push(callback); - }); - self.requestQueue = queque; + var request = self.currentRequest.request; + if(request.transport.readyState < 4) + request.transport.abort(); + //Logger.warn('## aborted: setting current request to null'); + self.endCurrentRequest(); } + self.tryNextRequest(); } }) @@ -676,7 +667,7 @@ Object.extend(Prado.CallbackRequest, Ajax.Responders.register({onComplete : function(request) { if(request.options.HasPriority) - Prado.CallbackRequest.abortCurrentRequest(); + Prado.CallbackRequest.tryNextRequest(); }}); //Add HTTP exception respones when logger is enabled. @@ -816,7 +807,7 @@ Prado.CallbackRequest.prototype = //override parameter and postBody options. Object.extend(this.options, { - postBody : this._getPostData(), +// postBody : this._getPostData(), parameters : '' }); @@ -2221,70 +2212,32 @@ Prado.WebUI.TAutoComplete = Class.extend(Prado.WebUI.TAutoComplete, */ Prado.WebUI.TTimeTriggeredCallback = Base.extend( { - count : 0, - timeout : 0, - constructor : function(options) { - this.options = Object.extend( - { - Interval : 1, - DecayRate : 0 - }, options || {}) - - this.onComplete = this.options.onComplete; + this.options = Object.extend({ Interval : 1 }, options || {}); Prado.WebUI.TTimeTriggeredCallback.register(this); }, startTimer : function() { - this.options.onComplete = this.onRequestComplete.bind(this); - this.timer = setTimeout(this.onTimerEvent.bind(this), 200); + setTimeout(this.onTimerEvent.bind(this), 100); + if(typeof(this.timer) == 'undefined' || this.timer == null) + this.timer = setInterval(this.onTimerEvent.bind(this),this.options.Interval*1000); }, stopTimer : function() { - (this.onComplete || Prototype.emptyFunction).apply(this, arguments); - this.options.onComplete = undefined; - clearTimeout(this.timer); - this.timer = undefined; - this.count = 0; + if(typeof(this.timer) != 'undefined') + { + clearInterval(this.timer); + this.timer = null; + } }, onTimerEvent : function() { - this.options.params = this.timeout/1000; var request = new Prado.CallbackRequest(this.options.EventTarget, this.options); request.dispatch(); - }, - - 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 diff --git a/framework/Web/Javascripts/js/debug/prado.js b/framework/Web/Javascripts/js/debug/prado.js index aaae6bad..4ab0a415 100644 --- a/framework/Web/Javascripts/js/debug/prado.js +++ b/framework/Web/Javascripts/js/debug/prado.js @@ -3389,9 +3389,11 @@ Prado.WebUI.TTextBox = Class.extend(Prado.WebUI.PostBackControl, { onInit : function(options) { + this.options=options; if(options['TextMode'] != 'MultiLine') Event.observe(this.element, "keydown", this.handleReturnKey.bind(this)); - Event.observe(this.element, "change", Prado.PostBack.bindEvent(this,options)); + if(this.options['AutoPostBack']==true) + Event.observe(this.element, "change", Prado.PostBack.bindEvent(this,options)); }, handleReturnKey : function(e) @@ -3401,8 +3403,19 @@ Prado.WebUI.TTextBox = Class.extend(Prado.WebUI.PostBackControl, var target = Event.element(e); if(target) { - Event.fireEvent(target, "change"); - Event.stop(e); + if(this.options['AutoPostBack']==true) + { + Event.fireEvent(target, "change"); + Event.stop(e); + } + else + { + if(this.options['CausesValidation'] && typeof(Prado.Validation) != "undefined") + { + if(!Prado.Validation.validate(this.options['FormID'], this.options['ValidationGroup'], $(this.options['ID']))) + return Event.stop(e); + } + } } } } @@ -3504,7 +3517,7 @@ Prado.WebUI.TCheckBoxList = Base.extend( var checkBoxOptions = Object.extend( { ID : options.ListID+"_c"+i, - EventTarget : options.ListID+"$c"+i + EventTarget : options.ListName+"$c"+i }, options); new Prado.WebUI.TCheckBox(checkBoxOptions); } @@ -3520,7 +3533,7 @@ Prado.WebUI.TRadioButtonList = Base.extend( var radioButtonOptions = Object.extend( { ID : options.ListID+"_c"+i, - EventTarget : options.ListID+"$c"+i + EventTarget : options.ListName+"$c"+i }, options); new Prado.WebUI.TRadioButton(radioButtonOptions); } diff --git a/framework/Web/Javascripts/prado/activecontrols3.js b/framework/Web/Javascripts/prado/activecontrols3.js index cb787571..e30fb702 100644 --- a/framework/Web/Javascripts/prado/activecontrols3.js +++ b/framework/Web/Javascripts/prado/activecontrols3.js @@ -145,70 +145,32 @@ Prado.WebUI.TAutoComplete = Class.extend(Prado.WebUI.TAutoComplete, */ Prado.WebUI.TTimeTriggeredCallback = Base.extend( { - count : 0, - timeout : 0, - constructor : function(options) { - this.options = Object.extend( - { - Interval : 1, - DecayRate : 0 - }, options || {}) - - this.onComplete = this.options.onComplete; + this.options = Object.extend({ Interval : 1 }, options || {}); Prado.WebUI.TTimeTriggeredCallback.register(this); }, startTimer : function() { - this.options.onComplete = this.onRequestComplete.bind(this); - this.timer = setTimeout(this.onTimerEvent.bind(this), 200); + setTimeout(this.onTimerEvent.bind(this), 100); + if(typeof(this.timer) == 'undefined' || this.timer == null) + this.timer = setInterval(this.onTimerEvent.bind(this),this.options.Interval*1000); }, stopTimer : function() { - (this.onComplete || Prototype.emptyFunction).apply(this, arguments); - this.options.onComplete = undefined; - clearTimeout(this.timer); - this.timer = undefined; - this.count = 0; + if(typeof(this.timer) != 'undefined') + { + clearInterval(this.timer); + this.timer = null; + } }, onTimerEvent : function() { - this.options.params = this.timeout/1000; var request = new Prado.CallbackRequest(this.options.EventTarget, this.options); request.dispatch(); - }, - - 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 diff --git a/framework/Web/Javascripts/prado/ajax3.js b/framework/Web/Javascripts/prado/ajax3.js index c5402ea4..f540813c 100644 --- a/framework/Web/Javascripts/prado/ajax3.js +++ b/framework/Web/Javascripts/prado/ajax3.js @@ -14,6 +14,9 @@ Object.extend(Ajax.Request.prototype, if (event == 'Complete') { + if(this.header('X-PRADO-REDIRECT')) + document.location.href = this.header('X-PRADO-REDIRECT'); + if ((this.header('Content-type') || '').match(/^text\/javascript/i)) { try @@ -119,10 +122,6 @@ Object.extend(Prado.CallbackRequest, * Page state header name. */ PAGESTATE_HEADER : 'X-PRADO-PAGESTATE', - /** - * Current requests in progress. - */ - currentRequest : null, requestQueue : [], @@ -264,25 +263,6 @@ Object.extend(Prado.CallbackRequest, return null; }, - /** - * Dispatch a priority request, it will call abortRequestInProgress first. - */ - dispatchPriorityRequest : function(callback) - { - var self = Prado.CallbackRequest; - - callback.request = new Ajax.Request(callback.url, callback.options); - callback.timeout = setTimeout(function() - { - //Logger.warn("priority timeout"); - self.abortCurrentRequest(); - },callback.options.RequestTimeOut); - - //Logger.info("dispatched "+this.currentRequest) - self.currentRequest = callback; - return true; - }, - /** * Dispatch a normal request, no timeouts or aborting of requests. */ @@ -296,23 +276,19 @@ Object.extend(Prado.CallbackRequest, /** * Abort the current priority request in progress. */ - abortCurrentRequest : function() + tryNextRequest : function() { var self = Prado.CallbackRequest; - var inProgress = self.currentRequest; - //Logger.info("aborting ... "+inProgress); - if(inProgress) + //Logger.debug('trying next request'); + if(typeof(self.currentRequest) == 'undefined' || self.currentRequest==null) { - clearTimeout(inProgress.timeout); - self.currentRequest = null; - //Logger.info("aborted"); - //abort if not ready. - if(inProgress.request.transport.readyState < 4) - inProgress.request.transport.abort(); - return self.dispatchQueue(); + if(self.requestQueue.length > 0) + return self.dispatchQueue(); + //else + //Logger.warn('empty queque'); } - else - return self.dispatchQueue(); +// else + // Logger.warn('current request ' + self.currentRequest.id); }, /** @@ -334,51 +310,66 @@ Object.extend(Prado.CallbackRequest, { if(typeof(Logger) != "undefined") Logger.warn("Missing page state:"+data); +// Logger.warn('## bad state: setting current request to null'); + self.endCurrentRequest(); + //self.tryNextRequest(); return false; } } + self.endCurrentRequest(); + // Logger.warn('## state updated: setting current request to null'); + // self.tryNextRequest(); return true; }, enqueue : function(callback) { var self = Prado.CallbackRequest; - if(self.currentRequest==null) - self.dispatchPriorityRequest(callback); - else - self.requestQueue.push(callback); - //Logger.info("current queque length="+self.requestQueue.length); + self.requestQueue.push(callback); + //Logger.warn("equeued "+callback.id+", current queque length="+self.requestQueue.length); + self.tryNextRequest(); }, dispatchQueue : function() { var self = Prado.CallbackRequest; - //Logger.info("dispatching queque, length="+self.requestQueue.length+" request="+self.currentRequest); - if(self.requestQueue.length > 0) + //Logger.warn("dispatching queque, length="+self.requestQueue.length+" request="+self.currentRequest); + var callback = self.requestQueue.shift(); + self.currentRequest = callback; + + //get data + callback.options.postBody = callback._getPostData(), + + callback.request = new Ajax.Request(callback.url, callback.options); + callback.timeout = setTimeout(function() { - var callback = self.requestQueue.shift(); - //Logger.info("do dispatch request"); - return self.dispatchPriorityRequest(callback); - } - return false; + //Logger.warn("priority timeout"); + self.abortRequest(callback.id); + },callback.options.RequestTimeOut); + //Logger.debug("dispatched "+self.currentRequest.id + " ...") + }, + + endCurrentRequest : function() + { + var self = Prado.CallbackRequest; + clearTimeout(self.currentRequest.timeout); + self.currentRequest=null; }, abortRequest : function(id) { - //Logger.info("abort id="+id); + //Logger.warn("abort id="+id); var self = Prado.CallbackRequest; - if(self.currentRequest != null && self.currentRequest.id == id) - self.abortCurrentRequest(); - else + if(typeof(self.currentRequest) != 'undefined' + && self.currentRequest != null && self.currentRequest.id == id) { - var queque = []; - self.requestQueue.each(function(callback) - { - if(callback.id != id) - queque.push(callback); - }); - self.requestQueue = queque; + var request = self.currentRequest.request; + if(request.transport.readyState < 4) + request.transport.abort(); + //Logger.warn('## aborted: setting current request to null'); + self.endCurrentRequest(); } + self.tryNextRequest(); } }) @@ -388,7 +379,7 @@ Object.extend(Prado.CallbackRequest, Ajax.Responders.register({onComplete : function(request) { if(request.options.HasPriority) - Prado.CallbackRequest.abortCurrentRequest(); + Prado.CallbackRequest.tryNextRequest(); }}); //Add HTTP exception respones when logger is enabled. @@ -528,7 +519,7 @@ Prado.CallbackRequest.prototype = //override parameter and postBody options. Object.extend(this.options, { - postBody : this._getPostData(), +// postBody : this._getPostData(), parameters : '' }); diff --git a/framework/Web/Javascripts/prado/controls.js b/framework/Web/Javascripts/prado/controls.js index c26026ae..97969f87 100644 --- a/framework/Web/Javascripts/prado/controls.js +++ b/framework/Web/Javascripts/prado/controls.js @@ -137,9 +137,11 @@ Prado.WebUI.TTextBox = Class.extend(Prado.WebUI.PostBackControl, { onInit : function(options) { + this.options=options; if(options['TextMode'] != 'MultiLine') Event.observe(this.element, "keydown", this.handleReturnKey.bind(this)); - Event.observe(this.element, "change", Prado.PostBack.bindEvent(this,options)); + if(this.options['AutoPostBack']==true) + Event.observe(this.element, "change", Prado.PostBack.bindEvent(this,options)); }, handleReturnKey : function(e) @@ -149,8 +151,19 @@ Prado.WebUI.TTextBox = Class.extend(Prado.WebUI.PostBackControl, var target = Event.element(e); if(target) { - Event.fireEvent(target, "change"); - Event.stop(e); + if(this.options['AutoPostBack']==true) + { + Event.fireEvent(target, "change"); + Event.stop(e); + } + else + { + if(this.options['CausesValidation'] && typeof(Prado.Validation) != "undefined") + { + if(!Prado.Validation.validate(this.options['FormID'], this.options['ValidationGroup'], $(this.options['ID']))) + return Event.stop(e); + } + } } } } @@ -252,7 +265,7 @@ Prado.WebUI.TCheckBoxList = Base.extend( var checkBoxOptions = Object.extend( { ID : options.ListID+"_c"+i, - EventTarget : options.ListID+"$c"+i + EventTarget : options.ListName+"$c"+i }, options); new Prado.WebUI.TCheckBox(checkBoxOptions); } @@ -268,7 +281,7 @@ Prado.WebUI.TRadioButtonList = Base.extend( var radioButtonOptions = Object.extend( { ID : options.ListID+"_c"+i, - EventTarget : options.ListID+"$c"+i + EventTarget : options.ListName+"$c"+i }, options); new Prado.WebUI.TRadioButton(radioButtonOptions); } diff --git a/framework/Web/THttpResponse.php b/framework/Web/THttpResponse.php index 3a6d0aa3..3b8c0842 100644 --- a/framework/Web/THttpResponse.php +++ b/framework/Web/THttpResponse.php @@ -81,7 +81,7 @@ class THttpResponse extends TModule implements ITextWriter * @var THttpResponseAdapter adapter. */ private $_adapter; - + /** * Destructor. * Flushes any existing content in buffer. @@ -91,7 +91,7 @@ class THttpResponse extends TModule implements ITextWriter //if($this->_bufferOutput) // @ob_end_flush(); } - + /** * @param THttpResponseAdapter response adapter */ @@ -99,7 +99,7 @@ class THttpResponse extends TModule implements ITextWriter { $this->_adapter=$adapter; } - + /** * @return THttpResponseAdapter response adapter, null if not exist. */ @@ -107,7 +107,7 @@ class THttpResponse extends TModule implements ITextWriter { return $this->_adapter; } - + /** * @return boolean true if adapter exists, false otherwise. */ @@ -250,7 +250,7 @@ class THttpResponse extends TModule implements ITextWriter { echo $str; } - + /** * Sends a file back to user. * Make sure not to output anything else after calling this method. @@ -313,6 +313,19 @@ class THttpResponse extends TModule implements ITextWriter * the current request will be inserted at the beginning. */ public function redirect($url) + { + if($this->getHasAdapter()) + $this->_adapter->httpRedirect($url); + else + $this->httpRedirect($url); + } + + /** + * Redirect the browser to another URL and exists the current application. + * @param string URL to be redirected to. If the URL is a relative one, the base URL of + * the current request will be inserted at the beginning. + */ + public function httpRedirect($url) { if(!$this->getApplication()->getRequestCompleted()) $this->getApplication()->onEndRequest(); @@ -342,7 +355,7 @@ class THttpResponse extends TModule implements ITextWriter else $this->flushContent(); } - + /** * Outputs the buffered content, sends content-type and charset header. */ @@ -351,7 +364,7 @@ class THttpResponse extends TModule implements ITextWriter Prado::trace("Flushing output",'System.Web.THttpResponse'); $this->sendContentTypeHeader(); if($this->_bufferOutput) - ob_flush(); + ob_flush(); } /** @@ -474,7 +487,7 @@ class THttpResponse extends TModule implements ITextWriter else return $this->createNewHtmlWriter($type, $this); } - + /** * Create a new html writer intance. * @param string type of HTML writer to be created. diff --git a/framework/Web/THttpResponseAdapter.php b/framework/Web/THttpResponseAdapter.php index beb585d4..8a1c86bb 100644 --- a/framework/Web/THttpResponseAdapter.php +++ b/framework/Web/THttpResponseAdapter.php @@ -12,7 +12,7 @@ /** * THttpResponseAdapter class. - * + * * THttpResponseAdapter allows the base http response class to change behaviour * without change the class hierachy. * @@ -27,7 +27,7 @@ class THttpResponseAdapter extends TApplicationComponent * @var THttpResponse the response object the adapter is attached. */ private $_response; - + /** * Constructor. Attach a response to be adapted. * @param THttpResponse the response object the adapter is to attach to. @@ -36,7 +36,7 @@ class THttpResponseAdapter extends TApplicationComponent { $this->_response=$response; } - + /** * @return THttpResponse the response object adapted. */ @@ -44,7 +44,7 @@ class THttpResponseAdapter extends TApplicationComponent { return $this->_response; } - + /** * This method is invoked when the response flushes the content and headers. * Default implementation calls the attached response flushContent method. @@ -53,7 +53,16 @@ class THttpResponseAdapter extends TApplicationComponent { $this->_response->flushContent(); } - + + /** + * This method is invoked when the response is to redirect to another page. + * @param string new url to redirect to. + */ + public function httpRedirect($url) + { + $this->_response->httpRedirect($url); + } + /** * This method is invoked when a new HtmlWriter needs to be created. * Default implementation calls the attached response createNewHtmlWriter method. diff --git a/framework/Web/UI/ActiveControls/TActiveLinkButton.php b/framework/Web/UI/ActiveControls/TActiveLinkButton.php index 019c002c..9b30fffc 100644 --- a/framework/Web/UI/ActiveControls/TActiveLinkButton.php +++ b/framework/Web/UI/ActiveControls/TActiveLinkButton.php @@ -93,7 +93,7 @@ class TActiveLinkButton extends TLinkButton implements IActiveControl, ICallback { parent::setText($value); if($this->getActiveControl()->canUpdateClientSide()) - $this->getPage()->getCallbackClient()->replaceContent($this, $value); + $this->getPage()->getCallbackClient()->update($this, $value); } /** diff --git a/framework/Web/UI/ActiveControls/TActivePageAdapter.php b/framework/Web/UI/ActiveControls/TActivePageAdapter.php index 2df19053..514b6880 100644 --- a/framework/Web/UI/ActiveControls/TActivePageAdapter.php +++ b/framework/Web/UI/ActiveControls/TActivePageAdapter.php @@ -45,6 +45,11 @@ class TActivePageAdapter extends TControlAdapter */ const CALLBACK_PAGESTATE_HEADER = 'X-PRADO-PAGESTATE'; + /** + * Callback redirect url header name. + */ + const CALLBACK_REDIRECT = 'X-PRADO-REDIRECT'; + /** * @var ICallbackEventHandler callback event handler. */ @@ -112,7 +117,21 @@ class TActivePageAdapter extends TControlAdapter public function renderCallbackResponse($writer) { Prado::trace("ActivePage renderCallbackResponse()",'System.Web.UI.ActiveControls.TActivePageAdapter'); - $this->renderResponse($writer); + if(($url = $this->getResponse()->getAdapter()->getRedirectedUrl())===null) + $this->renderResponse($writer); + else + $this->redirect($url); + } + + /** + * Redirect url on the client-side using javascript. + * @param string new url to load. + */ + protected function redirect($url) + { + if(!$this->getApplication()->getRequestCompleted()) + $this->getApplication()->onEndRequest(); + $this->getResponse()->appendHeader(self::CALLBACK_REDIRECT.': '.$url); } /** diff --git a/framework/Web/UI/ActiveControls/TAutoComplete.php b/framework/Web/UI/ActiveControls/TAutoComplete.php index a886e732..07fa652b 100644 --- a/framework/Web/UI/ActiveControls/TAutoComplete.php +++ b/framework/Web/UI/ActiveControls/TAutoComplete.php @@ -36,18 +36,20 @@ Prado::using('System.Web.UI.ActiveControls.TActiveTextBox'); * other properties of the repeater can be access via the {@link getSuggestions Suggestions} * property (e.g. they can be set in the .page templates). * - * To return the list of suggestions back to the browser, in your {@link onSuggestion OnSuggestion} - * event handler, do + * To return the list of suggestions back to the browser, supply a non-empty data source + * and call databind. For example, * * function autocomplete_suggestion($sender, $param) * { * $token = $param->getCallbackParameter(); //the partial word to match * $sender->setDataSource($this->getSuggestionsFor($token)); //set suggestions * $sender->dataBind(); - * $sender->render($param->getNewWriter()); //sends suggestion back to browser. * } * * + * The suggestion will be rendered when the {@link dataBind()} method is called + * during a callback request. + * * TAutoComplete allows multiple suggestions within one textbox with each * word or phrase separated by any characters specified in the * {@link setSeparator Separator} property. The {@link setFrequency Frequency} @@ -168,6 +170,17 @@ class TAutoComplete extends TActiveTextBox implements INamingContainer $this->getSuggestions()->setDataSource($data); } + /** + * Overrides parent implementation. Callback {@link renderSuggestions()} when + * page's IsCallback property is true. + */ + public function dataBind() + { + parent::dataBind(); + if($this->getPage()->getIsCallback()) + $this->renderSuggestions($this->getResponse()->createHtmlWriter()); + } + /** * @return TPanel suggestion results panel. */ @@ -232,24 +245,21 @@ class TAutoComplete extends TActiveTextBox implements INamingContainer } /** - * Flush and returns the suggestions content back to the browser client. + * Renders the suggestions during a callback respones. * @param THtmlWriter the renderer. */ - public function render($writer) + public function renderCallback($writer) { - if(!$this->getPage()->getIsCallback()) - parent::render($writer); - if($this->getActiveControl()->canUpdateClientSide()) - $this->renderSuggestions($writer); + $this->renderSuggestions($writer); } /** * Renders the suggestions repeater. * @param THtmlWriter the renderer. */ - protected function renderSuggestions($writer) + public function renderSuggestions($writer) { - if($this->getSuggestions()->getItems()->getCount() > 0) + if($this->getActiveControl()->canUpdateClientSide()) { $this->getSuggestions()->render($writer); $boundary = $writer->getWriter()->getBoundary(); diff --git a/framework/Web/UI/ActiveControls/TCallbackResponseAdapter.php b/framework/Web/UI/ActiveControls/TCallbackResponseAdapter.php index 922e6cc6..6e3fb01e 100755 --- a/framework/Web/UI/ActiveControls/TCallbackResponseAdapter.php +++ b/framework/Web/UI/ActiveControls/TCallbackResponseAdapter.php @@ -37,6 +37,8 @@ class TCallbackResponseAdapter extends THttpResponseAdapter */ private $_data; + private $_redirectUrl=null; + /** * Returns a new instance of THtmlWriter. * An instance of TCallbackResponseWriter is created to hold the content. @@ -75,6 +77,25 @@ class TCallbackResponseAdapter extends THttpResponseAdapter { return $this->_data; } + + /** + * Delay the redirect until we process the rest of the page. + * @param string new url to redirect to. + */ + public function httpRedirect($url) + { + if($url[0]==='/') + $url=$this->getRequest()->getBaseUrl().$url; + $this->_redirectUrl=str_replace('&','&',$url); + } + + /** + * @return string new url for callback response to redirect to. + */ + public function getRedirectedUrl() + { + return $this->_redirectUrl; + } } /** diff --git a/framework/Web/UI/ActiveControls/TTimeTriggeredCallback.php b/framework/Web/UI/ActiveControls/TTimeTriggeredCallback.php index 10923d03..45e33f81 100644 --- a/framework/Web/UI/ActiveControls/TTimeTriggeredCallback.php +++ b/framework/Web/UI/ActiveControls/TTimeTriggeredCallback.php @@ -25,11 +25,6 @@ Prado::using('System.Web.UI.ActiveControls.TCallback'); * {@link stopTimer()}. The timer can be automatically started when * {@link setStartTimerOnLoad StartTimerOnLoad} is true. * - * 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 * @version $Id$ * @package System.Web.UI.ActiveControls @@ -56,44 +51,6 @@ class TTimeTriggeredCallback extends TCallback $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. */ @@ -121,7 +78,7 @@ class TTimeTriggeredCallback extends TCallback */ public function setStartTimerOnLoad($value) { - $this->setViewState('StartTimerOnLoad', + $this->setViewState('StartTimerOnLoad', TPropertyValue::ensureBoolean($value), false); } @@ -141,8 +98,6 @@ class TTimeTriggeredCallback extends TCallback $options['ID'] = $this->getClientID(); $options['EventTarget']= $this->getUniqueID(); $options['Interval'] = $this->getInterval(); - $options['DecayRate'] = $this->getDecayRate(); - $options['DecayType'] = $this->getDecayType(); return $options; } diff --git a/framework/Web/UI/ActiveControls/TValueTriggeredCallback.php b/framework/Web/UI/ActiveControls/TValueTriggeredCallback.php index 3ec830b8..e0320c6b 100644 --- a/framework/Web/UI/ActiveControls/TValueTriggeredCallback.php +++ b/framework/Web/UI/ActiveControls/TValueTriggeredCallback.php @@ -15,10 +15,8 @@ * * Observes the value with {@link setPropertyName PropertyName} of a * control with {@link setControlID ControlID}. Changes to the observed - * property value will trigger a new callback request. The values are - * observed using a {@link setPollingInterval PollingInterval} (in seconds). - * That is, the property is checked for changes every - * {@link setPollingInterval PollingInterval} seconds. + * property value will trigger a new callback request. The property value is checked + * for changes every{@link setInterval Interval} seconds. * * A {@link setDecayRate DecayRate} can be set to increase the polling * interval linearly if no changes are observed. Once a change is @@ -53,11 +51,19 @@ class TValueTriggeredCallback extends TTriggeredCallback * Default is 1 second. * @param float polling interval in seconds. */ - public function setPollingInterval($value) + public function setInterval($value) { $this->setViewState('Interval', TPropertyValue::ensureFloat($value), 1); } + /** + * @return float polling interval, 1 second default. + */ + public function getInterval() + { + return $this->getViewState('Interval', 1); + } + /** * Gets the decay rate between callbacks. Default is 0; * @return float decay rate between callbacks. @@ -79,14 +85,6 @@ class TValueTriggeredCallback extends TTriggeredCallback $this->setViewState('Decay', $decay); } - /** - * @return float polling interval, 1 second default. - */ - public function getPollingInterval() - { - return $this->getViewState('Interval', 1); - } - /** * @return array list of timer options for client-side. */ @@ -94,7 +92,7 @@ class TValueTriggeredCallback extends TTriggeredCallback { $options = parent::getTriggerOptions(); $options['PropertyName'] = $this->getPropertyName(); - $options['Interval'] = $this->getPollingInterval(); + $options['Interval'] = $this->getInterval(); $options['Decay'] = $this->getDecayRate(); return $options; } diff --git a/framework/Web/UI/WebControls/TTextBox.php b/framework/Web/UI/WebControls/TTextBox.php index 588830f0..e8ad92db 100644 --- a/framework/Web/UI/WebControls/TTextBox.php +++ b/framework/Web/UI/WebControls/TTextBox.php @@ -156,7 +156,7 @@ class TTextBox extends TWebControl implements IPostBackDataHandler, IValidatable $writer->addAttribute('disabled','disabled'); if($isEnabled && $this->getEnableClientScript() - && $this->getAutoPostBack() + && ( $this->getAutoPostBack() || $textMode===TTextBoxMode::SingleLine) && $page->getClientSupportsJavaScript()) { $this->renderClientControlScript($writer); @@ -192,6 +192,7 @@ class TTextBox extends TWebControl implements IPostBackDataHandler, IValidatable { $options['ID'] = $this->getClientID(); $options['EventTarget'] = $this->getUniqueID(); + $options['AutoPostBack'] = $this->getAutoPostBack(); $options['CausesValidation'] = $this->getCausesValidation(); $options['ValidationGroup'] = $this->getValidationGroup(); $options['TextMode'] = $this->getTextMode(); diff --git a/framework/interfaces.php b/framework/interfaces.php index d0e5c6aa..f37325c8 100644 --- a/framework/interfaces.php +++ b/framework/interfaces.php @@ -290,7 +290,7 @@ interface IBindable * @author Wei Zhuo * @version $Id$ * @package System - * @since 3.0 + * @since 3.1 */ interface IActiveControl { @@ -309,7 +309,7 @@ interface IActiveControl * @author Wei Zhuo * @version $Id$ * @package System - * @since 3.0 + * @since 3.1 */ interface ICallbackEventHandler { -- cgit v1.2.3