diff options
-rw-r--r-- | .gitattributes | 1 | ||||
-rw-r--r-- | HISTORY | 2 | ||||
-rw-r--r-- | build.xml | 2 | ||||
-rw-r--r-- | buildscripts/classtree/ExtensionReadme.html | 20 | ||||
-rw-r--r-- | demos/quickstart/protected/pages/Configurations/AppConfig.page | 57 | ||||
-rw-r--r-- | demos/quickstart/protected/pages/GettingStarted/NewFeatures.page | 12 | ||||
-rw-r--r-- | framework/I18N/core/data/fr_CA.dat | 2 | ||||
-rw-r--r-- | framework/TApplication.php | 61 | ||||
-rw-r--r-- | framework/Web/TUrlMapping.php | 79 |
9 files changed, 206 insertions, 30 deletions
diff --git a/.gitattributes b/.gitattributes index d9f56505..a8cce7ac 100644 --- a/.gitattributes +++ b/.gitattributes @@ -803,6 +803,7 @@ buildscripts/chmbuilder/classes/pages/Classes.page -text buildscripts/chmbuilder/classes/pages/MainLayout.tpl -text buildscripts/chmbuilder/classes/pages/style.css -text buildscripts/classtree/DWExtensionReadme.txt -text +buildscripts/classtree/ExtensionReadme.html -text buildscripts/jGrouseDoc/3rdparty/ant/LICENSE -text buildscripts/jGrouseDoc/3rdparty/ant/LICENSE.dom -text buildscripts/jGrouseDoc/3rdparty/ant/LICENSE.sax -text @@ -8,6 +8,8 @@ Version 3.2.2 to be released ENH: Issue #433 - Prado object-creation performance micro-optimizations (gabor) BUG: Issue #434 - Buttons stops working properly after response->writeFile (ctrlaltca) BUG: Issue #435 - TWizard + No ID = Prototype Error (ctrlaltca) +BUG: Issue #436 - French Canadian date formats should be the same in TDateFormat and TDatePicker (ctrlaltca) +ENH: Issue #439 - Module lazy loading (ctrlaltca) Version 3.2.1 Jan 19, 2013 @@ -325,7 +325,7 @@ var_dump($sqlmap->queryForList('products-with-price', 50)); <fileset refid="test-tools" />
</copy>
- <copy file="buildscripts/classtree/DWExtensionReadme.txt" tofile="${build.src.dir}/editors/Dreamweaver/readme.txt" />
+ <copy file="buildscripts/classtree/ExtensionReadme.html" tofile="${build.src.dir}/editors/ExtensionReadme.html" />
<copy file="framework/pradolite.php" tofile="${build.src.dir}/framework/pradolite.php" />
<copy file="framework/prado-cli.php" tofile="${build.src.dir}/framework/prado-cli.php" />
diff --git a/buildscripts/classtree/ExtensionReadme.html b/buildscripts/classtree/ExtensionReadme.html new file mode 100644 index 00000000..fed1205c --- /dev/null +++ b/buildscripts/classtree/ExtensionReadme.html @@ -0,0 +1,20 @@ +<html> +<head> +<title>Extension Readme</title> +</head> +<body> +<p> +This directory used to contain the editor's extensions for PRADO. +</p> +<p>They have been moved elsewhere; we suggest you to download the most +up-to-date versions at <a href="http://code.google.com/p/prado3/downloads/list" >PRADO's google code page</a> +</p> +<p>Currently we provide extensions for the following editors: +<ul> +<li><a href="http://www.adobe.com/it/products/dreamweaver.html">Adobe Dreamweaver</a></li> +<li><a href="http://notepad-plus-plus.org">Notepad++</a></li> +<li><a href="http://inotai.com">Intype</a></li> +<li><a href="http://macromates.com">TextMate</a></li> +<li><a href="http://www.sublimetext.com">Sublime Text (using the TextMate extension)</a></li> +</ul> +</p>
\ No newline at end of file diff --git a/demos/quickstart/protected/pages/Configurations/AppConfig.page b/demos/quickstart/protected/pages/Configurations/AppConfig.page index 83f1bc7e..7887d959 100644 --- a/demos/quickstart/protected/pages/Configurations/AppConfig.page +++ b/demos/quickstart/protected/pages/Configurations/AppConfig.page @@ -56,4 +56,61 @@ An external configuration file has the same format as described above. Although By default without explicit configuration, a PRADO application will load a few core modules, such as <tt>THttpRequest</tt>, <tt>THttpResponse</tt>, etc. It will also provide the <tt>TPageService</tt> as a default service. Configuration and usage of these modules and services are covered in individual sections of this tutorial. Note, if your application takes default settings for these modules and service, you do not need to provide an application configuration. However, if these modules or services are not sufficient, or you want to change their behavior by configuring their property values, you will need an application configuration.
</p>
+<com:SinceVersion Version="3.2.2" />
+<p class="block-content">
+By default PRADO instanciates all modules defined in the application configuration at the beginning of the application lifecycle. This can hit the application performance if you have a lot of modules defined but not used at every request.
+Since version 3.2.2 you can set the <tt>lazy</tt> property on modules defined in the application configuration to enable the lazy loading of that module.
+
+<com:TTextHighlighter Language="xml" CssClass="source block-content">
+ <modules>
+ <module id="ModuleID" class="ModuleClass" lazy="true" PropertyName="PropertyValue" ... />
+ </modules>
+</com:TTextHighlighter>
+
+A module with the <tt>lazy</tt> property set won't be instanciated until the first time it gets actually used by the application:
+
+<com:TTextHighlighter Language="php" CssClass="source block-content">
+ // requesting the lazy module to the application will instanciate it
+ Prado::getApplication()->getModule('ModuleID');
+</com:TTextHighlighter>
+</p>
+
+<com:SinceVersion Version="3.2" />
+<p class="block-content">
+Since version 3.2 the application configuration can be stored in PHP array format in a file named <tt>application.php</tt>.
+The format of the configuration file is exactly the same of its XML counterpart, but following the PHP syntax.
+</p>
+
+<com:TTextHighlighter Language="php" CssClass="source block-content">
+<?php
+return array(
+ 'application' => array(
+ 'PropertyName' => 'PropertyValue'
+ ),
+ 'modules' => array(
+ 'ModuleID' => array(
+ 'class' => 'ModuleClass',
+ 'properties' => array(
+ 'PropertyName' => 'PropertyValue'
+ ),
+ ),
+ ),
+ 'services' => array(
+ 'ServiceID' => array(
+ 'class' => 'ServiceClass',
+ 'properties' => array(
+ 'PropertyName' => 'PropertyValue'
+ ),
+ ),
+ ),
+);
+</com:TTextHighlighter>
+
+The use of a PHP application configuration must be defined in the <tt>TApplication</tt> constructor, tipically located in the <tt>index.php</tt> entry script:
+
+<com:TTextHighlighter Language="php" CssClass="source block-content">
+$application=new TApplication('protected',false,TApplication::CONFIG_TYPE_PHP);
+$application->run();
+</com:TTextHighlighter>
+
</com:TContent>
diff --git a/demos/quickstart/protected/pages/GettingStarted/NewFeatures.page b/demos/quickstart/protected/pages/GettingStarted/NewFeatures.page index 98adc925..3db90fdc 100644 --- a/demos/quickstart/protected/pages/GettingStarted/NewFeatures.page +++ b/demos/quickstart/protected/pages/GettingStarted/NewFeatures.page @@ -6,11 +6,17 @@ This page summarizes the main new features that are introduced in each PRADO release. </p> +<h2>Version 3.2.2</h2> +<ul> +<li>TUrlMappingPattern support for constant parameters</li> +<li>Lazy module loading in application configuration</li> +</ul> + <h2 id="8001">Version 3.2.1</h2> <ul> -<li>TSecurityManager has been enhanced to support all the ciphers available in php</a></li> -<li>Added a new UrlFormat for TUrlManager: HiddenPath; works like the 'Path' format, but hides the entryscript.php name</a></li> -<li>Updated external packages</a></li> +<li>TSecurityManager has been enhanced to support all the ciphers available in php</li> +<li>Added a new UrlFormat for TUrlManager: HiddenPath; works like the 'Path' format, but hides the entryscript.php name</li> +<li>Updated external packages</li> </ul> <h2 id="8001">Version 3.2.0</h2> diff --git a/framework/I18N/core/data/fr_CA.dat b/framework/I18N/core/data/fr_CA.dat index fb152bf0..855fe7a6 100644 --- a/framework/I18N/core/data/fr_CA.dat +++ b/framework/I18N/core/data/fr_CA.dat @@ -1 +1 @@ -a:4:{s:10:"Currencies";a:2:{s:3:"CAD";a:2:{i:0;s:1:"$";i:1;s:15:"dollar canadien";}s:3:"USD";a:2:{i:0;s:4:"$ US";i:1;s:22:"dollar des États-Unis";}}s:14:"NumberPatterns";a:4:{i:0;s:20:"#,##0.###;-#,##0.###";i:1;s:24:"#,##0.00 ¤;(#,##0.00¤)";i:2;s:6:"#,##0%";i:3;s:3:"#E0";}s:7:"Version";a:1:{i:0;s:3:"1.2";}s:8:"calendar";a:1:{s:9:"gregorian";a:3:{s:26:"DateTimeElements:intvector";a:2:{i:0;i:1;i:1;i:4;}s:16:"DateTimePatterns";a:9:{i:0;s:24:"HH' h 'mm' min 'ss' s 'z";i:1;s:10:"HH:mm:ss z";i:2;s:8:"HH:mm:ss";i:3;s:5:"HH:mm";i:4;s:16:"EEEE d MMMM yyyy";i:5;s:11:"d MMMM yyyy";i:6;s:8:"yy-MM-dd";i:7;s:8:"yy-MM-dd";i:8;s:7:"{1} {0}";}s:17:"weekend:intvector";a:4:{i:0;i:7;i:1;i:0;i:2;i:1;i:3;i:86400000;}}}}
\ No newline at end of file +a:4:{s:10:"Currencies";a:2:{s:3:"CAD";a:2:{i:0;s:1:"$";i:1;s:15:"dollar canadien";}s:3:"USD";a:2:{i:0;s:4:"$ US";i:1;s:22:"dollar des États-Unis";}}s:14:"NumberPatterns";a:4:{i:0;s:20:"#,##0.###;-#,##0.###";i:1;s:24:"#,##0.00 ¤;(#,##0.00¤)";i:2;s:6:"#,##0%";i:3;s:3:"#E0";}s:7:"Version";a:1:{i:0;s:3:"1.2";}s:8:"calendar";a:1:{s:9:"gregorian";a:3:{s:26:"DateTimeElements:intvector";a:2:{i:0;i:1;i:1;i:4;}s:16:"DateTimePatterns";a:9:{i:0;s:24:"HH' h 'mm' min 'ss' s 'z";i:1;s:10:"HH:mm:ss z";i:2;s:8:"HH:mm:ss";i:3;s:5:"HH:mm";i:4;s:16:"EEEE d MMMM yyyy";i:5;s:11:"d MMMM yyyy";i:6;s:10:"yyyy-MM-dd";i:7;s:8:"yy-MM-dd";i:8;s:7:"{1} {0}";}s:17:"weekend:intvector";a:4:{i:0;i:7;i:1;i:0;i:2;i:1;i:3;i:86400000;}}}}
\ No newline at end of file diff --git a/framework/TApplication.php b/framework/TApplication.php index 1a41af2b..c1787b8f 100644 --- a/framework/TApplication.php +++ b/framework/TApplication.php @@ -205,10 +205,14 @@ class TApplication extends TComponent */ private $_service; /** - * @var array list of application modules + * @var array list of loaded application modules */ private $_modules=array(); /** + * @var array list of application modules yet to be loaded + */ + private $_lazyModules=array(); + /** * @var TMap list of application parameters */ private $_parameters; @@ -685,9 +689,9 @@ class TApplication extends TComponent * Adds a module to application. * Note, this method does not do module initialization. * @param string ID of the module - * @param IModule module object + * @param IModule module object or null if the module has not been loaded yet */ - public function setModule($id,IModule $module) + public function setModule($id,IModule $module=null) { if(isset($this->_modules[$id])) throw new TConfigurationException('application_moduleid_duplicated',$id); @@ -700,10 +704,22 @@ class TApplication extends TComponent */ public function getModule($id) { - return isset($this->_modules[$id])?$this->_modules[$id]:null; + if(!array_key_exists($id, $this->_modules)) + return null; + + // force loading of a lazy module + if($this->_modules[$id]===null) + { + $module = $this->internalLoadModule($id, true); + $module[0]->init($module[1]); + } + + return $this->_modules[$id]; } /** + * Returns a list of application modules indexed by module IDs. + * Modules that have not been loaded yet are returned as null objects. * @return array list of loaded application modules, indexed by module IDs */ public function getModules() @@ -938,6 +954,28 @@ class TApplication extends TComponent return 'TApplicationConfiguration'; } + protected function internalLoadModule($id, $force=false) + { + list($moduleClass, $initProperties, $configElement)=$this->_lazyModules[$id]; + if(isset($initProperties['lazy']) && $initProperties['lazy'] && !$force) + { + Prado::trace("Postponed loading of lazy module $id ({$moduleClass})",'System.TApplication'); + $this->setModule($id, null); + return null; + } + + Prado::trace("Loading module $id ({$moduleClass})",'System.TApplication'); + $module=Prado::createComponent($moduleClass); + foreach($initProperties as $name=>$value) + { + if($name==='lazy') continue; + $module->setSubProperty($name,$value); + } + $this->setModule($id,$module); + unset($this->_lazyModules[$id]); + + return array($module,$configElement); + } /** * Applies an application configuration. * @param TApplicationConfiguration the configuration @@ -982,18 +1020,11 @@ class TApplication extends TComponent $modules=array(); foreach($config->getModules() as $id=>$moduleConfig) { - Prado::trace("Loading module $id ({$moduleConfig[0]})",'System.TApplication'); - list($moduleClass, $initProperties, $configElement)=$moduleConfig; - $module=Prado::createComponent($moduleClass); if(!is_string($id)) - { - $id='_module'.count($this->_modules); - $initProperties['id']=$id; - } - $this->setModule($id,$module); - foreach($initProperties as $name=>$value) - $module->setSubProperty($name,$value); - $modules[]=array($module,$configElement); + $id='_module'.count($this->_lazyModules); + $this->_lazyModules[$id]=$moduleConfig; + if($module = $this->internalLoadModule($id)) + $modules[]=$module; } foreach($modules as $module) $module[0]->init($module[1]); diff --git a/framework/Web/TUrlMapping.php b/framework/Web/TUrlMapping.php index 0b6e517e..b5a09f14 100644 --- a/framework/Web/TUrlMapping.php +++ b/framework/Web/TUrlMapping.php @@ -450,7 +450,7 @@ class TUrlMapping extends TUrlManager * * <url ServiceParameter="adminpages.*" pattern="admin/{*}/{id}" parameters.id="\d+" /> * - * To enable automatic parameter encoding in a path format fro wildcard patterns you can set + * To enable automatic parameter encoding in a path format from wildcard patterns you can set * {@setUrlFormat UrlFormat} to 'Path': * * <url ServiceParameter="adminpages.*" pattern="admin/{*}" UrlFormat="Path" /> @@ -465,6 +465,17 @@ class TUrlMapping extends TUrlManager * * <tt>.../index.php/admin/listuser/param1-value1/param2-value2</tt>. * + * Since 3.2.2 you can also add a list of "constants" parameters that can be used just + * like the original "parameters" parameters, except that the supplied value will be treated + * as a simple string constant instead of a regular expression. For example + * + * <url ServiceParameter="MyPage" pattern="/mypage/mypath/list/detail/{pageidx}" parameters.pageidx="\d+" constants.listtype="detailed"/> + * <url ServiceParameter="MyPage" pattern="/mypage/mypath/list/summary/{pageidx}" parameters.pageidx="\d+" constants.listtype="summarized"/> + * + * These rules, when matched by the actual request, will make the application see a "lisstype" parameter present + * (even through not supplied in the request) and equal to "detailed" or "summarized", depending on the friendly url matched. + * The constants is practically a table-based validation and translation of specified, fixed-set parameter values. + * * @author Wei Zhuo <weizhuo[at]gmail[dot]com> * @version $Id$ * @package System.Web @@ -485,10 +496,14 @@ class TUrlMappingPattern extends TComponent */ private $_pattern; /** - * @var TMap parameter regular expressions. + * @var TAttributeCollection parameter regular expressions. */ private $_parameters; /** + * @var TAttributeCollection of constant parameters. + */ + protected $_constants; + /** * @var string regular expression pattern. */ private $_regexp=''; @@ -551,12 +566,15 @@ class TUrlMappingPattern extends TComponent $params=array(); $values=array(); if ($this->_parameters) - foreach($this->_parameters as $key=>$value) { - $params[]='{'.$key.'}'; - $values[]='(?P<'.$key.'>'.$value.')'; + foreach($this->_parameters as $key=>$value) + { + $params[]='{'.$key.'}'; + $values[]='(?P<'.$key.'>'.$value.')'; + } } - if ($this->getIsWildCardPattern()) { + if ($this->getIsWildCardPattern()) + { $params[]='{*}'; // service parameter must not contain '=' and '/' $values[]='(?P<'.$this->getServiceID().'>[^=/]+)'; @@ -676,6 +694,20 @@ class TUrlMappingPattern extends TComponent } /** + * @return TAttributeCollection constanst parameter key value pairs. + * @since 3.2.2 + */ + public function getConstants() + { + if (!$this->_constants) + { + $this->_constants = new TAttributeCollection; + $this->_constants->setCaseSensitive(true); + } + return $this->_constants; + } + + /** * Uses URL pattern (or full regular expression if available) to * match the given url path. * @param THttpRequest the request module @@ -712,6 +744,12 @@ class TUrlMappingPattern extends TComponent unset($matches['urlparams']); } + if(count($matches) > 0 && $this->_constants) + { + foreach($this->_constants->toArray() as $key=>$value) + $matches[$key] = $value; + } + return $matches; } @@ -759,7 +797,7 @@ class TUrlMappingPattern extends TComponent * Changing the UrlFormat will affect {@link constructUrl} and how GET variables * are parsed. * @param THttpRequestUrlFormat the format of URLs. - * @param since 3.1.4 + * @since 3.1.4 */ public function setUrlFormat($value) { @@ -814,10 +852,23 @@ class TUrlMappingPattern extends TComponent if(!$this->_customUrl || $this->getPattern()===null) return false; if ($this->_parameters) - foreach($this->_parameters as $key=>$value) { - if(!isset($getItems[$key])) - return false; + foreach($this->_parameters as $key=>$value) + { + if(!isset($getItems[$key])) + return false; + } + } + + if ($this->_constants) + { + foreach($this->_constants->toArray() as $key=>$value) + { + if (!isset($getItems[$key])) + return false; + if ($getItems[$key]!=$value) + return false; + } } return true; } @@ -832,6 +883,14 @@ class TUrlMappingPattern extends TComponent */ public function constructUrl($getItems,$encodeAmpersand,$encodeGetItems) { + if ($this->_constants) + { + foreach($this->_constants->toArray() as $key=>$value) + { + unset($getItems[$key]); + } + } + $extra=array(); $replace=array(); // for the GET variables matching the pattern, put them in the URL path |