From 9cc6b7fffd31f4b9ee9aceef9224c84dcf28aeb8 Mon Sep 17 00:00:00 2001 From: xue <> Date: Tue, 4 Jul 2006 23:25:41 +0000 Subject: Merge from 3.0 branch till 1239. --- HISTORY | 7 + UPGRADE | 3 + build.xml | 2 + buildscripts/phing/bin/phing.php | 4 + buildscripts/texbuilder/quickstart.tex | 6 +- .../quickstart/protected/pages/Controls/Pager.page | 2 +- framework/Collections/TList.php | 4 +- framework/Collections/TMap.php | 4 +- framework/Exceptions/messages.txt | 2 + framework/Web/THttpResponse.php | 2 +- framework/Web/UI/WebControls/TClientScript.php | 154 +++++++++++++++++++-- framework/Web/UI/WebControls/TDataGrid.php | 32 +++-- framework/Web/UI/WebControls/TFileUpload.php | 2 +- framework/Web/UI/WebControls/TStyleSheet.php | 78 +++++++++++ framework/Web/UI/WebControls/TTable.php | 2 +- index.html | 2 +- .../features/protected/pages/ClientScripTest.page | 30 ++++ .../features/protected/pages/test.js | 4 + 18 files changed, 306 insertions(+), 34 deletions(-) create mode 100644 framework/Web/UI/WebControls/TStyleSheet.php create mode 100644 tests/FunctionalTests/features/protected/pages/ClientScripTest.page create mode 100644 tests/FunctionalTests/features/protected/pages/test.js diff --git a/HISTORY b/HISTORY index d47ddf2e..f23dc280 100644 --- a/HISTORY +++ b/HISTORY @@ -10,6 +10,13 @@ NEW: TSessionPageStatePersister (Qiang) NEW: SQLMap (Wei) NEW: TFeedService, TRssFeedDocument (Knut, Qiang) +Version 3.0.3 August 6, 2006 +============================ +BUG: Ticket#264 - Typos in some exception throw statements (Knut) +BUG: Ticket#268 - THttpResponse.redirect() may fail for some browsers (Qiang) +BUG: TDataGrid may complain getting ItemType on a non-object if the grid is not data-bound (Qiang) +NEW: Added TStyleSheet (Wei) + Version 3.0.2 July 2, 2006 ========================== BUG: Ticket#182 - List and validator controls cause problem in child classes (Qiang) diff --git a/UPGRADE b/UPGRADE index 4640c9ca..61a84977 100644 --- a/UPGRADE +++ b/UPGRADE @@ -14,6 +14,9 @@ version B between A and C, you need to following the instructions for both A and B. +Upgrading from v3.0.2 +--------------------- + Upgrading from v3.0.1 --------------------- - Postback enabled control will always disable default client-side browser action. diff --git a/build.xml b/build.xml index ad468d0a..5e995d97 100644 --- a/build.xml +++ b/build.xml @@ -42,6 +42,8 @@ + + diff --git a/buildscripts/phing/bin/phing.php b/buildscripts/phing/bin/phing.php index 880adf41..7d0a774a 100644 --- a/buildscripts/phing/bin/phing.php +++ b/buildscripts/phing/bin/phing.php @@ -13,6 +13,7 @@ ini_set('track_errors', 1); /* set classpath */ +/* if (getenv('PHP_CLASSPATH')) { // define('PHP_CLASSPATH', getenv('PHP_CLASSPATH') . PATH_SEPARATOR . get_include_path()); define('PHP_CLASSPATH', realpath(dirname(__FILE__).'/../classes') . PATH_SEPARATOR . get_include_path()); @@ -20,6 +21,9 @@ if (getenv('PHP_CLASSPATH')) { } else { define('PHP_CLASSPATH', get_include_path()); } +*/ +define('PHP_CLASSPATH', realpath(dirname(__FILE__).'/../classes') . PATH_SEPARATOR . get_include_path()); +ini_set('include_path', PHP_CLASSPATH); require_once 'phing/Phing.php'; diff --git a/buildscripts/texbuilder/quickstart.tex b/buildscripts/texbuilder/quickstart.tex index 35ba86a5..a0553658 100644 --- a/buildscripts/texbuilder/quickstart.tex +++ b/buildscripts/texbuilder/quickstart.tex @@ -42,7 +42,7 @@ %----------------- TITLE -------------- -\title{\Huge \bfseries PRADO v3.0.2 Quickstart Tutorial +\title{\Huge \bfseries PRADO v3.0.3 Quickstart Tutorial \thanks{Copyright 2005-2006. All Rights Reserved.} } \author{Qiang Xue and Wei Zhuo} @@ -68,7 +68,7 @@ Prado quick start doc \chapter*{License} \addcontentsline{toc}{chapter}{License} PRADO is free software released under the terms of the following BSD license.\\ -Copyright 2004-2006, PradoSoft (http://www.pradosoft.com)\\ +Copyright 2004-2006, The PRADO Group (http://www.pradosoft.com)\\ All rights reserved. Redistribution and use in source and binary forms, with or without @@ -81,7 +81,7 @@ this list of conditions and the following disclaimer. this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -\item Neither the name of the developer nor the names of its contributors may +\item Neither the name of the PRADO Group nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. \end{enumerate} diff --git a/demos/quickstart/protected/pages/Controls/Pager.page b/demos/quickstart/protected/pages/Controls/Pager.page index 3c74d0de..821eab71 100644 --- a/demos/quickstart/protected/pages/Controls/Pager.page +++ b/demos/quickstart/protected/pages/Controls/Pager.page @@ -1,6 +1,6 @@ -

TPager

+

TPager

diff --git a/framework/Collections/TList.php b/framework/Collections/TList.php index 5b27a02e..015781cb 100644 --- a/framework/Collections/TList.php +++ b/framework/Collections/TList.php @@ -152,7 +152,7 @@ class TList extends TComponent implements IteratorAggregate,ArrayAccess throw new TInvalidDataValueException('list_index_invalid',$index); } else - throw new TInvalidOperation('list_readonly',get_class($this)); + throw new TInvalidOperationException('list_readonly',get_class($this)); } /** @@ -201,7 +201,7 @@ class TList extends TComponent implements IteratorAggregate,ArrayAccess throw new TInvalidDataValueException('list_index_invalid',$index); } else - throw new TInvalidOperation('list_readonly',get_class($this)); + throw new TInvalidOperationException('list_readonly',get_class($this)); } /** diff --git a/framework/Collections/TMap.php b/framework/Collections/TMap.php index 28508e1d..e3a26e5f 100644 --- a/framework/Collections/TMap.php +++ b/framework/Collections/TMap.php @@ -123,7 +123,7 @@ class TMap extends TComponent implements IteratorAggregate,ArrayAccess if(!$this->_r) $this->_d[$key]=$value; else - throw new TInvalidOperation('map_readonly',get_class($this)); + throw new TInvalidOperationException('map_readonly',get_class($this)); } /** @@ -146,7 +146,7 @@ class TMap extends TComponent implements IteratorAggregate,ArrayAccess return null; } else - throw new TInvalidOperation('map_readonly',get_class($this)); + throw new TInvalidOperationException('map_readonly',get_class($this)); } /** diff --git a/framework/Exceptions/messages.txt b/framework/Exceptions/messages.txt index 22b28a42..ff9ab1f3 100644 --- a/framework/Exceptions/messages.txt +++ b/framework/Exceptions/messages.txt @@ -320,6 +320,8 @@ databoundcontrol_datasourceid_inexistent = databoundcontrol_datasourceid_inexist databoundcontrol_datasourceid_invalid = databoundcontrol_datasourceid_invalid databoundcontrol_datamember_invalid = databoundcontrol_datamember_invalid +clientscript_invalid_file_position = Invalid file position '{1}' for TClientScript control '{0}', must be 'Head', 'Here' or 'Begin'. + callback_not_support_no_priority_state_update = Callback request does not support unprioritized pagestate update. callback_invalid_callback_options = '{1}' is not a valid TCallbackOptions control for Callback control '{0}'. callback_invalid_clientside_options = Callback ClientSide property must be either a string that is the ID of a TCallbackOptions control or an instance of TCallbackClientSideOptions.======= diff --git a/framework/Web/THttpResponse.php b/framework/Web/THttpResponse.php index e44d6cba..bba0cabc 100644 --- a/framework/Web/THttpResponse.php +++ b/framework/Web/THttpResponse.php @@ -316,7 +316,7 @@ class THttpResponse extends TModule implements ITextWriter $this->getApplication()->onEndRequest(); if($url[0]==='/') $url=$this->getRequest()->getBaseUrl().$url; - header('Location:'.$url); + header('Location: '.$url); exit(); } diff --git a/framework/Web/UI/WebControls/TClientScript.php b/framework/Web/UI/WebControls/TClientScript.php index 513f41c2..79279a93 100644 --- a/framework/Web/UI/WebControls/TClientScript.php +++ b/framework/Web/UI/WebControls/TClientScript.php @@ -13,21 +13,38 @@ /** * TClientScript class * - * Allows importing of Prado Client Scripts from template via the + * Allows importing of Prado Client Scripts from template via the * {@link setUsingPradoScripts UsingPradoScripts} property. Multiple Prado * client-scripts can be specified using comma delimited string of the * javascript library to include on the page. For example, - * + * * * * - * + * * The {@link setPreRenderControlTypes PreRenderControlTypes} property can * be used to specify that controls type/class names that should pre-render itself * even though they may not be rendered on the page. This is useful to publish * controls that require assets and is only visible after a callback response. - * - * @TODO May be use it to include stylesheets as well. + * + * Custom javascript files can be register using the {@link setScriptUrl ScriptUrl} + * property. + * + * /> + * + * + * Contents within TClientScript will be treated as javascript code and will be + * rendered. + * + * The {@link setScriptPosition ScriptPosition} property specifies where the script + * will be rendered. The allows values of {@link setScriptPosition ScriptPosition} are + * + * - Head -- renders the script within the <head> + * - Begin -- renders the script within and near the begining of TForm + * - Here -- renders the script inplace, this is the default + * - End -- renders the script within and near the end of TForm + * + * TODO: Allow binding expressions inside scripts * * @author Wei Zhuo * @version $Revision: $ $Date: $ @@ -36,6 +53,11 @@ */ class TClientScript extends TControl { + /** + * @var string body contents + */ + private $_content = ''; + /** * @return string comma delimited list of javascript libraries to included * on the page. @@ -44,29 +66,45 @@ class TClientScript extends TControl { return $this->getViewState('PradoScripts', ''); } - + /** * Include javascript library to the current page. The current supported * libraries are: "prado", "effects", "ajax", "validator", "logger", * "datepicker", "rico", "colorpicker". Library dependencies are * automatically resolved. - * + * * @param string comma delimited list of javascript libraries to include. */ public function setUsingPradoScripts($value) { $this->setViewState('PradoScripts', $value, ''); } - + + /** + * @return string custom javascript file url. + */ + public function getScriptUrl() + { + return $this->getViewState('ScriptUrl', ''); + } + + /** + * @param string custom javascript file url. + */ + public function setScriptUrl($value) + { + $this->setViewState('ScriptUrl', $value, ''); + } + /** - * @param string comma delimited list of controls that wish to be prerendered + * @param string comma delimited list of controls that wish to be prerendered * so as to publish its assets. */ public function setPreRenderControlTypes($value) { $this->setViewState('PreRenderControls', $value); } - + /** * @return string comma delimited list of controls types that require prerendering. */ @@ -74,7 +112,26 @@ class TClientScript extends TControl { return $this->getViewState('PreRenderControls', ''); } - + + /** + * @return string position the script should be rendered, default is 'Here'. + */ + public function getScriptPosition() + { + return $this->getViewState('ScriptPosition', 'Here'); + } + + /** + * Sets the position where the script will be rendered. + * The allow positions are 'Head', 'Begin', 'Here', and 'End', default is 'Here'. + * @param string script position 'Head', 'Begin', 'Here' or 'End'. + */ + public function setScriptPosition($value) + { + $this->setViewState('ScriptPosition', + TPropertyValue::ensureEnum($value, 'Head', 'Begin', 'Here', 'End'), 'Here'); + } + /** * Calls the client script manager to add each of the requested client * script libraries. @@ -91,9 +148,78 @@ class TClientScript extends TControl if(strlen($script) > 0) $cs->registerPradoScript($script); } + if($this->getEnabled(true)) + { + $this->registerCustomScriptFile(); + $this->registerCustomScript(); + } $this->preRenderControls($param); } - + + /** + * Registers the custom script file. + */ + protected function registerCustomScriptFile() + { + $scriptUrl = $this->getScriptUrl(); + if(strlen($scriptUrl)) + { + $position = $this->getScriptPosition(); + $cs = $this->getPage()->getClientScript(); + switch($this->getScriptPosition()) + { + case 'Head': + $cs->registerHeadScriptFile($scriptUrl, $scriptUrl); + break; + case 'Begin': + $cs->registerScriptFile($scriptUrl, $scriptUrl); + break; + case 'Here': + $this->_content .= TJavascript::renderScriptFile($scriptUrl); + break; + default : + throw new TConfigurationException('clientscript_invalid_file_position', + $this->getID(), $position); + } + } + } + + /** + * Renders the body content as javascript block. + * Overrides parent implementation, parent renderChildren method is called during + * {@link registerCustomScript}. + * @param THtmlWriter the renderer + */ + public function render($writer) + { + if($this->getEnabled(true) && strlen($this->_content) > 0) + $writer->write($this->_content); + } + + /** + * Registers the body content as scripts at specific locations. Calls + * {@link parent::renderChildren} to capture the body contents. + */ + protected function registerCustomScript() + { + $textWriter=new TTextWriter; + $this->renderChildren(new THtmlWriter($textWriter)); + $script=$textWriter->flush(); + if(strlen($script)>0) + { + $cs = $this->getPage()->getClientScript(); + $position = $this->getScriptPosition(); + if($position == 'Here') + $this->_content .= TJavaScript::renderScriptBlock($script); + else + { + $key = sprintf('%08X', crc32($script)); + $method = 'register'.$position.'Script'; + $cs->{$method}($key, $script); + } + } + } + /** * PreRender other controls to allow them to publish their assets. Useful * when callback response components that require assets to be present on the page. @@ -110,8 +236,8 @@ class TClientScript extends TControl $control->setPage($this->getPage()); $control->onPreRender($param); } - } + } } } -?> \ No newline at end of file +?> diff --git a/framework/Web/UI/WebControls/TDataGrid.php b/framework/Web/UI/WebControls/TDataGrid.php index fead5344..f7697fec 100644 --- a/framework/Web/UI/WebControls/TDataGrid.php +++ b/framework/Web/UI/WebControls/TDataGrid.php @@ -213,7 +213,7 @@ class TDataGrid extends TBaseDataList implements INamingContainer if($object instanceof TDataGridColumn) $this->getColumns()->add($object); else - parent::addParsedObject($object); + parent::addParsedObject($object); // this is needed by EmptyTemplate } /** @@ -246,6 +246,14 @@ class TDataGrid extends TBaseDataList implements INamingContainer return $this->_items; } + /** + * @return integer number of items + */ + public function getItemCount() + { + return $this->_items?$this->_items->getCount():0; + } + /** * Creates a style object for the control. * This method creates a {@link TTableStyle} to be used by datagrid. @@ -892,13 +900,16 @@ class TDataGrid extends TBaseDataList implements INamingContainer { foreach($columns as $column) $column->initialize(); - if($allowPaging) - $this->_topPager=$this->createPager(); - $this->_header=$this->createItemInternal(-1,-1,self::IT_HEADER,false,null,$columns); $selectedIndex=$this->getSelectedItemIndex(); $editIndex=$this->getEditItemIndex(); for($index=0;$index<$itemCount;++$index) { + if($index===0) + { + if($allowPaging) + $this->_topPager=$this->createPager(); + $this->_header=$this->createItemInternal(-1,-1,self::IT_HEADER,false,null,$columns); + } if($index===$editIndex) $itemType=self::IT_EDITITEM; else if($index===$selectedIndex) @@ -910,9 +921,12 @@ class TDataGrid extends TBaseDataList implements INamingContainer $items->add($this->createItemInternal($index,$dsIndex,$itemType,false,null,$columns)); $dsIndex++; } - $this->_footer=$this->createItemInternal(-1,-1,self::IT_FOOTER,false,null,$columns); - if($allowPaging) - $this->_bottomPager=$this->createPager(); + if($index>0) + { + $this->_footer=$this->createItemInternal(-1,-1,self::IT_FOOTER,false,null,$columns); + if($allowPaging) + $this->_bottomPager=$this->createPager(); + } } if(!$dsIndex && $this->_emptyTemplate!==null) { @@ -1287,6 +1301,8 @@ class TDataGrid extends TBaseDataList implements INamingContainer foreach($this->getControls() as $index=>$item) { + if(!($item instanceof TDataGridItem) && !($item instanceof TDataGridPager)) + continue; $itemType=$item->getItemType(); switch($itemType) { @@ -1423,7 +1439,7 @@ class TDataGrid extends TBaseDataList implements INamingContainer $this->renderContents($writer); $control->renderEndTag($writer); } - else + else if($this->getViewState('ItemCount',0)>0) { $this->applyItemStyles(); if($this->_topPager) diff --git a/framework/Web/UI/WebControls/TFileUpload.php b/framework/Web/UI/WebControls/TFileUpload.php index 37689746..62c51ccf 100644 --- a/framework/Web/UI/WebControls/TFileUpload.php +++ b/framework/Web/UI/WebControls/TFileUpload.php @@ -189,7 +189,7 @@ class TFileUpload extends TWebControl implements IPostBackDataHandler, IValidata throw new TInvalidOperationException('fileupload_saveas_failed'); } else - throw new TInvalidOperation('fileupload_saveas_forbidden'); + throw new TInvalidOperationException('fileupload_saveas_forbidden'); } /** diff --git a/framework/Web/UI/WebControls/TStyleSheet.php b/framework/Web/UI/WebControls/TStyleSheet.php new file mode 100644 index 00000000..02ac40cd --- /dev/null +++ b/framework/Web/UI/WebControls/TStyleSheet.php @@ -0,0 +1,78 @@ + + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005 PradoSoft + * @license http://www.pradosoft.com/license/ + * @version $Revision: $ $Date: $ + * @package System.Web.UI.WebControls + */ + +/** + * TStyleSheet class. + * + * TStyleSheet represents the link to a stylesheet file and/or a piece of + * stylesheet code. To specify the link to a CSS file, set {@link setStyleSheetUrl StyleSheetUrl}. + * The child rendering result of TStyleSheet is treated as CSS code and + * is rendered within an appropriate style HTML element. + * Therefore, if the child content is not empty, you should place the TStyleSheet + * control in the head section of your page to conform to the HTML standard. + * If only CSS file URL is specified, you may place the control anywhere on your page + * and the style element will be rendered in the right position. + * + * @author Wei Zhuo + * @version : $ Tue Jul 4 04:38:16 EST 2006 $ + * @package System.Web.UI.WebControl + * @since 3.0.2 + */ +class TStyleSheet extends TControl +{ + /** + * @param string URL to the stylesheet file + */ + public function setStyleSheetUrl($value) + { + $this->setViewState('StyleSheetUrl', $value); + } + + /** + * @return string URL to the stylesheet file + */ + public function getStyleSheetUrl() + { + return $this->getViewState('StyleSheetUrl', ''); + } + + /** + * Registers the stylesheet file and content to be rendered. + * This method overrides the parent implementation and is invoked right before rendering. + * @param mixed event parameter + */ + public function onPreRender($param) + { + if($this->getEnabled(true)) + { + if(($url=$this->getStyleSheetUrl())!=='') + $this->getPage()->getClientScript()->registerStyleSheetFile($url,$url); + } + } + + /** + * Renders the control. + * This method overrides the parent implementation and renders nothing. + * @param ITextWriter writer + */ + public function render($writer) + { + if($this->getHasControls()) + { + $writer->write("\n"); + } + } +} + +?> \ No newline at end of file diff --git a/framework/Web/UI/WebControls/TTable.php b/framework/Web/UI/WebControls/TTable.php index 1c58c62e..ac61eb3f 100644 --- a/framework/Web/UI/WebControls/TTable.php +++ b/framework/Web/UI/WebControls/TTable.php @@ -129,7 +129,7 @@ class TTable extends TWebControl } /** - * @return TTableCellCollection list of {@link TTableCell} controls + * @return TTableRowCollection list of {@link TTableRow} controls */ public function getRows() { diff --git a/index.html b/index.html index 8e895f36..dd2f8582 100644 --- a/index.html +++ b/index.html @@ -7,7 +7,7 @@

PRADO Framework for PHP 5

-

Version 3.0.2, July 2, 2006
+

Version 3.0.3, August 6, 2006
Copyright© 2004-2006 by PradoSoft
All Rights Reserved.

diff --git a/tests/FunctionalTests/features/protected/pages/ClientScripTest.page b/tests/FunctionalTests/features/protected/pages/ClientScripTest.page new file mode 100644 index 00000000..8dbf7133 --- /dev/null +++ b/tests/FunctionalTests/features/protected/pages/ClientScripTest.page @@ -0,0 +1,30 @@ + +

ClientScript Test

+ + ScriptPosition="Head"> + if(typeof(ClientScriptInfo) == "undefined") + ClientScriptInfo = []; + ClientScriptInfo.push("ok 3?") + + + + if(typeof(ClientScriptInfo) == "undefined") + ClientScriptInfo = []; + ClientScriptInfo.push("ok 2!") + + + + + + + Event.observe("button1", "click", function() + { + element = $("<%= $this->label1->ClientID %>"); + if(element) + element.innerHTML = inspect(ClientScriptInfo); + else + alert("failed"); + }); + + +
\ No newline at end of file diff --git a/tests/FunctionalTests/features/protected/pages/test.js b/tests/FunctionalTests/features/protected/pages/test.js new file mode 100644 index 00000000..e8e80b19 --- /dev/null +++ b/tests/FunctionalTests/features/protected/pages/test.js @@ -0,0 +1,4 @@ +if(typeof(ClientScriptInfo) == "undefined") + ClientScriptInfo = []; + +ClientScriptInfo.push("ok") \ No newline at end of file -- cgit v1.2.3