From 0f34cca749fade963acd014aff526067b00bc49e Mon Sep 17 00:00:00 2001
From: ctrlaltca <>
Date: Fri, 8 Feb 2013 16:49:58 +0000
Subject: merged to trunk/ all the changes from branch/3.2 up to r3270

---
 framework/I18N/core/data/fr_CA.dat |  2 +-
 framework/TApplication.php         | 61 +++++++++++++++++++++--------
 framework/Web/TUrlMapping.php      | 79 +++++++++++++++++++++++++++++++++-----
 3 files changed, 116 insertions(+), 26 deletions(-)

(limited to 'framework')

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,9 +205,13 @@ 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
 	 */
@@ -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,9 +496,13 @@ 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.
 	 */
@@ -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().'>[^=/]+)';
@@ -675,6 +693,20 @@ class TUrlMappingPattern extends TComponent
 		$this->_parameters=$value;
 	}
 
+	/**
+	 * @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.
@@ -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
-- 
cgit v1.2.3