diff options
43 files changed, 1559 insertions, 236 deletions
| diff --git a/.gitattributes b/.gitattributes index e8b3efd0..1ba435cd 100644 --- a/.gitattributes +++ b/.gitattributes @@ -695,7 +695,9 @@ buildscripts/wikibuilder/dumpHTML.php -text  buildscripts/wikibuilder/external.png -text  buildscripts/wikibuilder/main.css -text  demos/address-book/index.php -text +demos/address-book/index_php.php -text  demos/address-book/protected/.htaccess -text +demos/address-book/protected/application.php -text  demos/address-book/protected/application.xml -text  demos/address-book/protected/pages/AddressProvider.php -text  demos/address-book/protected/pages/AddressRecord.php -text @@ -990,6 +992,7 @@ demos/blog-tutorial/themes/PradoSoft/mantissample.jpg -text  demos/blog-tutorial/themes/PradoSoft/pradologo.gif -text  demos/blog-tutorial/themes/PradoSoft/style.css -text  demos/blog/index.php -text +demos/blog/index_php.php -text  demos/blog/protected/.htaccess -text  demos/blog/protected/Common/BlogDataModule.php -text  demos/blog/protected/Common/BlogErrorHandler.php -text @@ -1000,6 +1003,7 @@ demos/blog/protected/Common/BlogUserManager.php -text  demos/blog/protected/Common/XListMenu.php -text  demos/blog/protected/Common/messages.txt -text  demos/blog/protected/Common/schema.sql -text +demos/blog/protected/Data/Settings.php -text  demos/blog/protected/Data/Settings.xml -text  demos/blog/protected/Layouts/MainLayout.php -text  demos/blog/protected/Layouts/MainLayout.tpl -text @@ -1011,6 +1015,7 @@ demos/blog/protected/Pages/Admin/PostMan.page -text  demos/blog/protected/Pages/Admin/PostMan.php -text  demos/blog/protected/Pages/Admin/UserMan.page -text  demos/blog/protected/Pages/Admin/UserMan.php -text +demos/blog/protected/Pages/Admin/config.php -text  demos/blog/protected/Pages/Admin/config.xml -text  demos/blog/protected/Pages/ErrorReport.page -text  demos/blog/protected/Pages/ErrorReport.php -text @@ -1028,6 +1033,7 @@ demos/blog/protected/Pages/Posts/NewPost.page -text  demos/blog/protected/Pages/Posts/NewPost.php -text  demos/blog/protected/Pages/Posts/ViewPost.page -text  demos/blog/protected/Pages/Posts/ViewPost.php -text +demos/blog/protected/Pages/Posts/config.php -text  demos/blog/protected/Pages/Posts/config.xml -text  demos/blog/protected/Pages/SearchPost.page -text  demos/blog/protected/Pages/SearchPost.php -text @@ -1051,22 +1057,26 @@ demos/blog/protected/Portlets/LoginPortlet.tpl -text  demos/blog/protected/Portlets/Portlet.php -text  demos/blog/protected/Portlets/SearchPortlet.php -text  demos/blog/protected/Portlets/SearchPortlet.tpl -text +demos/blog/protected/application.php -text  demos/blog/protected/application.xml -text  demos/blog/themes/Fall/style.css -text  demos/blog/themes/Spring/style.css -text  demos/blog/themes/Summer/style.css -text  demos/blog/themes/Winter/style.css -text  demos/chat/index.php -text +demos/chat/index_php.php -text  demos/chat/protected/.htaccess -text  demos/chat/protected/App_Code/ChatBufferRecord.php -text  demos/chat/protected/App_Code/ChatUserManager.php -text  demos/chat/protected/App_Code/ChatUserRecord.php -text  demos/chat/protected/App_Code/chat.db -text +demos/chat/protected/application.php -text  demos/chat/protected/application.xml -text  demos/chat/protected/pages/Home.page -text  demos/chat/protected/pages/Home.php -text  demos/chat/protected/pages/Login.page -text  demos/chat/protected/pages/Login.php -text +demos/chat/protected/pages/config.php -text  demos/chat/protected/pages/config.xml -text  demos/chat/protected/pages/send.gif -text  demos/chat/protected/pages/send.png -text @@ -1096,7 +1106,9 @@ demos/helloworld/protected/.htaccess -text  demos/helloworld/protected/pages/Home.page -text  demos/helloworld/protected/pages/Home.php -text  demos/northwind-db/index.php -text +demos/northwind-db/index_php.php -text  demos/northwind-db/protected/.htaccess -text +demos/northwind-db/protected/application.php -text  demos/northwind-db/protected/application.xml -text  demos/northwind-db/protected/data/Northwind.db -text  demos/northwind-db/protected/database/Category.php -text @@ -1115,6 +1127,7 @@ demos/northwind-db/protected/pages/NorthwindCrud.page -text  demos/northwind-db/protected/pages/NorthwindCrud.php -text  demos/northwind-db/protected/pages/northwind.gif -text  demos/personal/index.php -text +demos/personal/index_php.php -text  demos/personal/protected/.htaccess -text  demos/personal/protected/Common/LoginPortlet.php -text  demos/personal/protected/Common/LoginPortlet.tpl -text @@ -1130,7 +1143,9 @@ demos/personal/protected/Pages/Register.php -text  demos/personal/protected/Pages/Resume.page -text  demos/personal/protected/Pages/Settings.page -text  demos/personal/protected/Pages/UserLogin.page -text +demos/personal/protected/Pages/config.php -text  demos/personal/protected/Pages/config.xml -text +demos/personal/protected/application.php -text  demos/personal/protected/application.xml -text  demos/personal/themes/BlueTheme/buttons.skin -text  demos/personal/themes/BlueTheme/icon_profile.gif -text @@ -1834,10 +1849,12 @@ demos/soap/protected/pages/Home.page -text  demos/soap/protected/pages/Home.php -text  demos/soap/protected/webservices/SimpleService.php -text  demos/sqlmap/index.php -text +demos/sqlmap/index_php.php -text  demos/sqlmap/protected/.htaccess -text  demos/sqlmap/protected/APP_CODE/Person.php -text  demos/sqlmap/protected/App_Data/person.xml -text  demos/sqlmap/protected/App_Data/test.db -text +demos/sqlmap/protected/application.php -text  demos/sqlmap/protected/application.xml -text  demos/sqlmap/protected/pages/Manual/BigPicture.page -text  demos/sqlmap/protected/pages/Manual/BuildingTSqlMapper.page -text @@ -1872,6 +1889,7 @@ demos/sqlmap/protected/pages/Manual/Tutorial/example1.png -text  demos/sqlmap/protected/pages/Manual/Tutorial/grid1.png -text  demos/sqlmap/protected/pages/Manual/Tutorial/grid2.png -text  demos/sqlmap/protected/pages/Manual/WorkingWithDataMaps.page -text +demos/sqlmap/protected/pages/Manual/config.php -text  demos/sqlmap/protected/pages/Manual/config.xml -text  demos/sqlmap/protected/pages/Manual/diagram.png -text  demos/sqlmap/protected/pages/Sample/Home.page -text @@ -1880,6 +1898,7 @@ demos/sqlmap/protected/pages/Sample/crud1.php -text  demos/sqlmap/protected/pages/Sample/crud2.page -text  demos/sqlmap/protected/pages/Sample/crud2.php -text  demos/time-tracker/index.php -text +demos/time-tracker/index_php.php -text  demos/time-tracker/protected/.htaccess -text  demos/time-tracker/protected/App_Code/Dao/BaseDao.php -text  demos/time-tracker/protected/App_Code/Dao/CategoryDao.php -text @@ -1914,6 +1933,7 @@ demos/time-tracker/protected/App_Data/SQLite/users.xml -text  demos/time-tracker/protected/App_Data/TimeTrackerUserTypeHandler.php -text  demos/time-tracker/protected/App_Data/mysql4-sqlmap.xml -text  demos/time-tracker/protected/App_Data/sqlite-sqlmap.xml -text +demos/time-tracker/protected/application.php -text  demos/time-tracker/protected/application.xml -text  demos/time-tracker/protected/pages/TimeTracker/CategoryDataList.php -text  demos/time-tracker/protected/pages/TimeTracker/CategoryDataList.tpl -text @@ -1941,6 +1961,7 @@ demos/time-tracker/protected/pages/TimeTracker/UserCreate.page -text  demos/time-tracker/protected/pages/TimeTracker/UserCreate.php -text  demos/time-tracker/protected/pages/TimeTracker/UserList.page -text  demos/time-tracker/protected/pages/TimeTracker/UserList.php -text +demos/time-tracker/protected/pages/TimeTracker/config.php -text  demos/time-tracker/protected/pages/TimeTracker/config.xml -text  demos/time-tracker/protected/pages/Welcome.page -text  demos/time-tracker/tests/functional.php -text @@ -1,4 +1,6 @@ +/.cache  /.project +/.settings  /assets  buildscripts/chmbuilder/assets/*  buildscripts/chmbuilder/classes/runtime/* @@ -1,3 +1,6 @@ +Version 3.2 to be released +NEW: Issue#83 - PHP configuration style (Carl) +  Version 3.1.6 to be released  BUG: Issue#98 - Missing file in quickstart demo (Chrisotphe)  BUG: Issue#117 - Consider TValidationSummary.DisplayMode="HeaderOnly" if TValidationSummary.ShowMessageBox is set (Yves) @@ -1,5 +1,5 @@ -         Upgrading Instructions for PRADO Framework v3.1.6 +         Upgrading Instructions for PRADO Framework v3.2           =================================================  !!!IMPORTANT!!! diff --git a/demos/address-book/index_php.php b/demos/address-book/index_php.php new file mode 100644 index 00000000..17cf61ad --- /dev/null +++ b/demos/address-book/index_php.php @@ -0,0 +1,27 @@ +<?php +$frameworkPath='../../framework/prado.php'; + +/** The directory checks may be removed if performance is required **/ +$basePath=dirname(__FILE__); +$assetsPath=$basePath."/assets"; +$runtimePath=$basePath."/protected/runtime"; +$sqliteDbDir=$basePath."/protected/pages/"; +$sqliteDb=$sqliteDbDir.'sqlite.db'; + +if(!is_file($frameworkPath)) +	die("Unable to find prado framework path $frameworkPath."); +if(!is_writable($assetsPath)) +	die("Please make sure that the directory $assetsPath is writable by Web server process."); +if(!is_writable($runtimePath)) +	die("Please make sure that the directory $runtimePath is writable by Web server process."); +if(!is_writable($sqliteDbDir)) +	die("Please make sure that the directory $sqliteDbDir is writable by Web server process."); +if(!is_writable($sqliteDb)) +	die("Please make sure that the file $sqliteDbDir is writable by Web server process."); + +require_once($frameworkPath); + +$application=new TApplication('protected',false,TApplication::CONFIG_TYPE_PHP); +$application->run(); + +?>
\ No newline at end of file diff --git a/demos/address-book/protected/application.php b/demos/address-book/protected/application.php new file mode 100644 index 00000000..ace63d2d --- /dev/null +++ b/demos/address-book/protected/application.php @@ -0,0 +1,54 @@ +<?php + +return array( +	'application' => array( +		'id' => 'address-book', +		'mode' => 'Debug', +	), +	'paths' => array( +		'using'=>array( +			'System.Data.*', +			'System.Security.*', +			'System.Data.ActiveRecord.*', +			'System.Web.Services.*', +		) +	), +	'modules' => array( +		'sqlite-db' => array( +			'class' => 'TActiveRecordConfig', +			'database' => array( +				'ConnectionString' => 'sqlite:./protected/pages/sqlite.db', +			), +		), +		'users' => array( +			'class' => 'TUserManager', +			'properties' => array( +				'PasswordMode' => 'Clear', +			), +			'users' => array( +				array( +					'name'=>'demo', +					'password'=>'demo' +				), +			), +		), +		'auth' => array( +			'class' => 'System.Security.TAuthManager', +			'properties' => array( +				'userManager' => 'users', +				'loginPage' => 'Login', +			), +		), +	), +	'services' => array( +		'soap' => array( +			'class' => 'TSoapService', +			'address-book' => array( +				'properties' => array( +					'provider' => 'Application.pages.AddressProvider', +					'ClassMaps' => 'AddressRecord', +				), +			), +		), +	), +);
\ No newline at end of file diff --git a/demos/blog/index_php.php b/demos/blog/index_php.php new file mode 100644 index 00000000..a5434860 --- /dev/null +++ b/demos/blog/index_php.php @@ -0,0 +1,20 @@ +<?php + +$basePath=dirname(__FILE__); +$frameworkPath=$basePath.'/../../framework/prado.php'; +$assetsPath=$basePath.'/assets'; +$runtimePath=$basePath.'/protected/runtime'; +$dataPath=$basePath.'/protected/Data'; + +if(!is_writable($assetsPath)) +	die("Please make sure that the directory $assetsPath is writable by Web server process."); +if(!is_writable($runtimePath)) +	die("Please make sure that the directory $runtimePath is writable by Web server process."); +if(!is_writable($dataPath)) +	die("Please make sure that the directory $dataPath is writable by Web server process."); +if(!extension_loaded("sqlite")) +	die("SQLite PHP extension is required."); + +require_once($frameworkPath); +$application=new TApplication('protected',false,TApplication::CONFIG_TYPE_PHP); +$application->run();
\ No newline at end of file diff --git a/demos/blog/protected/Data/Settings.php b/demos/blog/protected/Data/Settings.php new file mode 100644 index 00000000..a4adcd9f --- /dev/null +++ b/demos/blog/protected/Data/Settings.php @@ -0,0 +1,13 @@ +<?php +return array( +	'SiteTitle' => 'MyBlog', +	'SiteSubtitle' => 'A Prado-driven weblog', +	'SiteOwner' => 'Prado User', +	'AdminEmail' => 'admin@example.com', +	'MultipleUser' => false, +	'AccountApproval' => false, +	'PostPerPage' => 6, +	'RecentComments' => 6, +	'PostApproval' => false, +	'ThemeName' => 'Winter' +);
\ No newline at end of file diff --git a/demos/blog/protected/Pages/Admin/config.php b/demos/blog/protected/Pages/Admin/config.php new file mode 100644 index 00000000..d392da4e --- /dev/null +++ b/demos/blog/protected/Pages/Admin/config.php @@ -0,0 +1,13 @@ +<?php +return array( +	'authorization' => array( +		array( +			'action' => 'allow', +			'roles' => 'admin', +		), +		array( +			'action' => 'deny', +			'users' => '*', +		), +	), +);
\ No newline at end of file diff --git a/demos/blog/protected/Pages/Posts/config.php b/demos/blog/protected/Pages/Posts/config.php new file mode 100644 index 00000000..8af0dd56 --- /dev/null +++ b/demos/blog/protected/Pages/Posts/config.php @@ -0,0 +1,20 @@ +<?php +return array( +	'authorization' => array( +		array( +			'action' => 'deny', +			'pages' => 'EditPost,NewPost,MyPost', +			'users' => '?', +		), +		array( +			'action' => 'allow', +			'pages' => 'NewCategory,EditCategory', +			'users' => 'admin', +		), +		array( +			'action' => 'deny', +			'pages' => 'NewCategory,EditCategory', +			'users' => '*', +		), +	) +);
\ No newline at end of file diff --git a/demos/blog/protected/application.php b/demos/blog/protected/application.php new file mode 100644 index 00000000..d7d7c97b --- /dev/null +++ b/demos/blog/protected/application.php @@ -0,0 +1,86 @@ +<?php +return array( +	'application' => array( +		'id' => 'blog', +		'mode' => 'Debug' +	), +	'paths' => array( +		'using' => array( +			'Application.Common.*', +		), +	), +	// Modules configured and loaded for all services +	'modules' => array( +		'request' => array( +			'class' => 'THttpRequest', +			'properties' => array( +				'UrlFormat' => 'Path', +				'UrlManager' => 'friendly-url', +			), +		), +		 +		'cache' => array( +			'class' => 'System.Caching.TSqliteCache', +		), +		 +		'error' => array( +			'class' => 'Application.Common.BlogErrorHandler', +		), +		array( +			'class' => 'System.Util.TLogRouter', +			'routes' => array( +				array( +					'class' => 'TFileLogRoute', +					'properties' => array( +						'Categories' => 'BlogApplication', +					), +				), +			), +		), +		array( +			'class' => 'System.Util.TParameterModule', +			'properties' => array( +				'ParameterFile' => 'Application.Data.Settings', +			), +		), +		'friendly-url' => array( +			'class' => 'System.Web.TUrlMapping', +			'properties' => array( +				'EnableCustomUrl' => true, +			), +			'urls' => array( +				array('properties' => array('ServiceParameter'=>'Posts.ViewPost','pattern'=>'post/{id}/?','parameters.id'=>'\d+')), +			), +		), +	), +	'services' => array( +		'page' => array( +			'class' => 'TPageService', +			'properties' => array( +				'BasePath' => 'Application.Pages', +				'DefaultPage' => 'Posts.ListPost', +			), +			'modules' => array( +				'users' => array( +					'class' => 'Application.Common.BlogUserManager', +				), +				'auth' => array( +					'class' => 'System.Security.TAuthManager', +					'properties' => array( +						'UserManager' => 'users', +						'LoginPage' => 'Posts.ListPost', +					), +				), +				'data' => array( +					'class' => 'Application.Common.BlogDataModule', +				), +			), +			'pages' => array( +				'properties' => array( +					'MasterClass' => 'Application.Layouts.MainLayout', +					'Theme' => 'Basic', +				), +			), +		), +	), +);
\ No newline at end of file diff --git a/demos/chat/index_php.php b/demos/chat/index_php.php new file mode 100644 index 00000000..88427e4a --- /dev/null +++ b/demos/chat/index_php.php @@ -0,0 +1,27 @@ +<?php + +$frameworkPath='../../framework/prado.php'; + +/** The directory checks may be removed if performance is required **/ +$basePath=dirname(__FILE__); +$assetsPath=$basePath."/assets"; +$runtimePath=$basePath."/protected/runtime"; + +$sqliteDbDir = $basePath."/protected/App_Code"; +$sqliteDb = $sqliteDbDir."/chat.db"; + +if(!is_file($frameworkPath)) +	die("Unable to find prado framework path $frameworkPath."); +if(!is_writable($assetsPath)) +	die("Please make sure that the directory $assetsPath is writable by Web server process."); +if(!is_writable($runtimePath)) +	die("Please make sure that the directory $runtimePath is writable by Web server process."); +if(!is_writable($sqliteDbDir)) +	die("Please make sure that the directory $sqliteDbDir is writable by Web server process."); +if(!is_writable($sqliteDb)) +	die("Please make sure that the sqlite file $sqliteDb is writable by Web server process."); + +require_once($frameworkPath); + +$application=new TApplication('protected',false,TApplication::CONFIG_TYPE_PHP); +$application->run();
\ No newline at end of file diff --git a/demos/chat/protected/application.php b/demos/chat/protected/application.php new file mode 100644 index 00000000..ae4e1d8c --- /dev/null +++ b/demos/chat/protected/application.php @@ -0,0 +1,25 @@ +<?php +return array( +	'application' => array( +		'id' => 'Chat', +		'mode' => 'Debug' +	), +	'paths' => array( +		'using'=>array( +			'Application.App_Code.*', +			'System.Data.*', +			'System.Data.ActiveRecord.*', +			'System.Security.*', +			'System.Web.UI.ActiveControls.*', +		), +	), +	'modules' => array( +		'db' => array( +			'class' => 'TActiveRecordConfig', +			'properties' => array( +				'EnableCache' => 'true', +				'Database.ConnectionString'=>"sqlite:protected/App_Code/chat.db", +			) +		), +	), +);
\ No newline at end of file diff --git a/demos/chat/protected/pages/config.php b/demos/chat/protected/pages/config.php new file mode 100644 index 00000000..926bf150 --- /dev/null +++ b/demos/chat/protected/pages/config.php @@ -0,0 +1,31 @@ +<?php +return array( +	'modules' => array( +		'users' => array( +			'class' => 'ChatUserManager', +		), +		'auth' => array( +			'class' => 'TAuthManager', +			'properties' => array( +				'UserManager' => 'users', +				'LoginPage' => 'Login', +			), +		), +	), +	 +	'authorization' => array( +		array( +			'action' => 'allow', +			'pages' => 'Login', +			'users' => '?', +		), +		array( +			'action' => 'allow', +			'roles' => 'normal', +		), +		array( +			'action' => 'deny', +			'users' => '*', +		), +	), +);
\ No newline at end of file diff --git a/demos/northwind-db/index_php.php b/demos/northwind-db/index_php.php new file mode 100644 index 00000000..d3fe038b --- /dev/null +++ b/demos/northwind-db/index_php.php @@ -0,0 +1,26 @@ +<?php + +$basePath=dirname(__FILE__); +$frameworkPath=$basePath.'/../../framework/prado.php'; +$assetsPath=$basePath.'/assets'; +$runtimePath=$basePath.'/protected/runtime'; + +if(!is_file($frameworkPath)) +	die("Unable to find prado framework path $frameworkPath."); +if(!is_writable($assetsPath)) +	die("Please make sure that the directory $assetsPath is writable by Web server process."); +if(!is_writable($runtimePath)) +	die("Please make sure that the directory $runtimePath is writable by Web server process."); + +/** SQLite Northwind database file **/ +$sqlite_dir = $basePath.'/protected/data'; +$sqlite_db = $sqlite_dir.'/Northwind.db'; +if(!is_writable($sqlite_dir)) +	die("Please make sure that the directory $sqlite_dir is writable by Web server process."); +if(!is_writable($sqlite_db)) +	die("Please make sure that the sqlite database file $sqlite_db is writable by Web server process."); + +require_once($frameworkPath); + +$application=new TApplication('protected',false,TApplication::CONFIG_TYPE_PHP); +$application->run();
\ No newline at end of file diff --git a/demos/northwind-db/protected/application.php b/demos/northwind-db/protected/application.php new file mode 100644 index 00000000..2d6d4ec7 --- /dev/null +++ b/demos/northwind-db/protected/application.php @@ -0,0 +1,29 @@ +<?php +return array( +	'application' => array( +		'id' => 'northwind-db', +		'mode' => 'Debug' +	), +	'paths' => array( +		'using'=>array( +			'System.Data.*', +			'System.Data.ActiveRecord.*', +			'System.Data.ActiveRecord.Scaffold.*', +			'Application.database.*', +		), +	), +	'modules' => array( +		'db' => array( +			'class' => 'TActiveRecordConfig', +			'database' => array( +				'ConnectionString' => 'sqlite:protected/data/Northwind.db', +			), +		), +		'i81n' => array( +			'class' => 'System.I18N.TGlobalization', +			'properties' => array( +				'DefaultCharSet'=>'UTF-8', +			), +		), +	), +);
\ No newline at end of file diff --git a/demos/personal/index_php.php b/demos/personal/index_php.php new file mode 100644 index 00000000..cf57d82d --- /dev/null +++ b/demos/personal/index_php.php @@ -0,0 +1,13 @@ +<?php + +$basePath=dirname(__FILE__); +$frameworkPath=$basePath.'/../../framework/prado.php'; +$assetsPath=$basePath.'/assets'; + +if(!is_writable($assetsPath)) +	die("Please make sure that the directory $assetsPath is writable by Web server process."); + +require_once($frameworkPath); + +$application=new TApplication('protected',false,TApplication::CONFIG_TYPE_PHP); +$application->run();
\ No newline at end of file diff --git a/demos/personal/protected/Pages/Layout.tpl b/demos/personal/protected/Pages/Layout.tpl index 3ffb5306..d650a689 100644 --- a/demos/personal/protected/Pages/Layout.tpl +++ b/demos/personal/protected/Pages/Layout.tpl @@ -8,7 +8,7 @@  <div class="header">
  <h1>Your Name Here</h1>
 -<h2>My Personal Site</h2>
 +<h2><%$siteName%></h2>
  <div class="mainmenu">
  <com:MainMenu />
 diff --git a/demos/personal/protected/Pages/Settings.page b/demos/personal/protected/Pages/Settings.page index 48dfde96..f461fa13 100644 --- a/demos/personal/protected/Pages/Settings.page +++ b/demos/personal/protected/Pages/Settings.page @@ -1,4 +1,4 @@ -<com:TContent ID="main" >
 +<com:TContent ID="content" >
  Welcome, <com:TLabel Text=<%= $this->User->Name %> />!
  This page contains site settings accessible only to site admin.
  </com:TContent>
\ No newline at end of file diff --git a/demos/personal/protected/Pages/config.php b/demos/personal/protected/Pages/config.php new file mode 100644 index 00000000..7a42d866 --- /dev/null +++ b/demos/personal/protected/Pages/config.php @@ -0,0 +1,16 @@ +<?php +return array( +	'authorization' => array( +		array( +			'action' => 'deny', +			'pages' => 'Settings', +			'users' => '?', +		), +	), +	'pages' => array( +		'properties' => array( +			'MasterClass' => 'Application.Pages.Layout', +			'Theme' => 'White', +		), +	), +);
\ No newline at end of file diff --git a/demos/personal/protected/application.php b/demos/personal/protected/application.php new file mode 100644 index 00000000..0d9cadd4 --- /dev/null +++ b/demos/personal/protected/application.php @@ -0,0 +1,41 @@ +<?php +return array( +	'application' => array( +		'id' => 'personal', +		'mode' => 'Debug', +	), +	'paths' => array( +		'using'=>array('Application.common.*'), +	), +	'modules' => array(	 +	), +	'services' => array( +		'page' => array( +			'class' => 'TPageService', +			'properties' => array( +				'basePath' => 'Application.Pages', +			), +			'modules' => array( +				'users' => array( +					'class' => 'System.Security.TUserManager', +					'properties' => array( +						'passwordMode' => 'Clear', +					), +					'users' => array( +						array('name'=>'demo','password'=>'demo'), +					), +				), // users +				'auth' => array( +					'class' => 'System.Security.TAuthManager', +					'properties' => array( +						'userManager' => 'users', +						'loginPage' => 'UserLogin', +					), +				), +			), +		), +	), +	'parameters' => array( +		'siteName' => 'My Personal Site (PHP Config)', +	) +);
\ No newline at end of file diff --git a/demos/personal/protected/application.xml b/demos/personal/protected/application.xml index d2affe24..b67df94a 100644 --- a/demos/personal/protected/application.xml +++ b/demos/personal/protected/application.xml @@ -33,4 +33,7 @@        </modules>
      </service>
    </services>
 +  <parameters>
 +	<parameter id="siteName" value="My Personal Site" />
 +  </parameters>
  </application>
\ No newline at end of file diff --git a/demos/sqlmap/index_php.php b/demos/sqlmap/index_php.php new file mode 100644 index 00000000..4c382999 --- /dev/null +++ b/demos/sqlmap/index_php.php @@ -0,0 +1,18 @@ +<?php + +$basePath=dirname(__FILE__); +$frameworkPath='../../framework/prado.php'; +$assetsPath=$basePath."/assets"; +$runtimePath=$basePath."/protected/runtime"; + +if(!is_file($frameworkPath)) +	die("Unable to find prado framework path $frameworkPath."); +if(!is_writable($assetsPath)) +	die("Please make sure that the directory $assetsPath is writable by Web server process."); +if(!is_writable($runtimePath)) +	die("Please make sure that the directory $runtimePath is writable by Web server process."); + +require_once($frameworkPath); + +$application=new TApplication; +$application->run('protected',false,TApplication::CONFIG_TYPE_PHP);
\ No newline at end of file diff --git a/demos/sqlmap/protected/application.php b/demos/sqlmap/protected/application.php new file mode 100644 index 00000000..60d9549c --- /dev/null +++ b/demos/sqlmap/protected/application.php @@ -0,0 +1,22 @@ +<?php +return array( +	'application' => array( +		'id' => 'Database', +		'Mode' => 'Debug', +	), +	'paths' => array( +		'Example' => 'APP_CODE', +		'Quickstart' => '../../quickstart', +	), +	'using' => array( +		'Quickstart.protected.controls.*', +	), +	'services' => array( +		'page' => array( +			'class' => 'TPageService', +			'properties' => array( +				'DefaultPage' => 'Manual.Overview', +			), +		), +	), +);
\ No newline at end of file diff --git a/demos/sqlmap/protected/pages/Manual/config.php b/demos/sqlmap/protected/pages/Manual/config.php new file mode 100644 index 00000000..ca1ec772 --- /dev/null +++ b/demos/sqlmap/protected/pages/Manual/config.php @@ -0,0 +1,18 @@ +<?php +return array( +	'modules' => array( +		'theme' => array( +			'class' => 'System.Web.UI.TThemeManager', +			'properties' => array( +				'BasePath' => 'Quickstart.themes', +				'BaseUrl' => '../quickstart/themes', +			), +		), +	), +	'pages' => array( +		'properties' => array( +			'MasterClass' => 'Application.pages.Manual.Layout', +			'Theme' => 'PradoSoft', +		), +	), +);
\ No newline at end of file diff --git a/demos/time-tracker/index_php.php b/demos/time-tracker/index_php.php new file mode 100644 index 00000000..b74690e4 --- /dev/null +++ b/demos/time-tracker/index_php.php @@ -0,0 +1,33 @@ +<?php + +$basePath=dirname(__FILE__); +//$frameworkPath='../../framework/pradolite.php'; +$frameworkPath='../../framework/prado.php'; +$assetsPath=$basePath."/assets"; +$runtimePath=$basePath."/protected/runtime"; + +$sqlite_dir = $basePath."/protected/App_Data/SQLite"; +$sqlite_db = $sqlite_dir.'/time-tracker.db'; + +if(!is_file($frameworkPath)) +	die("Unable to find prado framework path $frameworkPath."); +if(!is_writable($assetsPath)) +	die("Please make sure that the directory $assetsPath is writable by Web server process."); +if(!is_writable($runtimePath)) +	die("Please make sure that the directory $runtimePath is writable by Web server process."); +if(!is_writable($sqlite_dir)) +	die("Please make sure that the directory $sqlite_dir is writable by Web server process."); +if(!is_writable($sqlite_db)) +	die("Please make sure that the sqlite database file $sqlite_dir is writable by Web server process."); + +require_once($frameworkPath); + +function h($text) +{ +	$app = Prado::getApplication()->getGlobalization(); +	$charset = $app ? $app->getCharset() : 'UTF-8'; +	return htmlentities($text, ENT_QUOTES, $charset); +} + +$application=new TApplication; +$application->run('protected',false,TApplication::CONFIG_TYPE_PHP);
\ No newline at end of file diff --git a/demos/time-tracker/protected/application.php b/demos/time-tracker/protected/application.php new file mode 100644 index 00000000..4fd65d04 --- /dev/null +++ b/demos/time-tracker/protected/application.php @@ -0,0 +1,49 @@ +<?php +return array( +	'application' => array( +		'id'=>'Time-Tracker', +		'Mode'=>'Debug' +	), +	'paths' => array( +		'aliases' => array( +			'Quickstart' => '../../quickstart', +		), +		'using' => array( +			'System.Data.*', +			'System.Security.*', +			'Application.App_Code.*', +			'Application.App_Code.Dao.*', +			'Application.App_Data.*', +		), +	), +	'modules' => array( +		'daos' => array( +			'class' => 'DaoManager', +			'properties' => array( +				'EnableCache' => 'true', +				'configFile' => 'Application.App_Data.sqlite-sqlmap', +			), +			'daos' => array( +				'UserDao' => 'Application.App_Code.Dao.UserDao', +				'ProjectDao' => 'Application.App_Code.Dao.ProjectDao', +				'TimeEntryDao' => 'Application.App_Code.Dao.TimeEntryDao', +				'CategoryDao' => 'Application.App_Code.Dao.CategoryDao', +				'ReportDao' => 'Application.App_Code.Dao.ReportDao', +			) +		), +		'globalization' => array( +			'class' => 'System.I18N.TGlobalization', +			'properties' => array( +				'CharSet' => 'UTF-8', +			), +		), +	), +	'services' => array( +		'page' => array( +			'class' => 'TPageService', +			'properties' => array( +				'DefaultPage' => 'TimeTracker.LogTimeEntry', +			), +		), +	), +);
\ No newline at end of file diff --git a/demos/time-tracker/protected/pages/TimeTracker/config.php b/demos/time-tracker/protected/pages/TimeTracker/config.php new file mode 100644 index 00000000..8668ca15 --- /dev/null +++ b/demos/time-tracker/protected/pages/TimeTracker/config.php @@ -0,0 +1,30 @@ +<?php +return array( +	'modules' => array( +		'users' => array( +			'class' => 'Application.App_Code.UserManager', +		), +		'auth' => array( +			'class' => 'Application.App_Code.TrackerAuthManager', +			'properties' => array( +				'UserManager' => 'users', +				'LoginPage' => 'TimeTracker.Login' +			), +		), +	), +	'authorization' => array( +		array('action'=>'allow','pages'=>'ProjectList, ProjectDetails, ReportResource, ReportProject','roles'=>'manager'), +		array('action'=>'allow','pages'=>'LogTimeEntry','roles'=>'consultant'), +		array('action'=>'allow','pages'=>'UserCrate,Logout,Login','users'=>'*'), +		array('action'=>'deny','users'=>'*'), +	), +	'pages' => array( +		'properties' => array( +			'MasterClass' => 'Application.pages.TimeTracker.MainLayout', +			'Theme' => 'TimeTracker', +		), +	), +	'parameters' => array( +		'NewUserRoles' => 'admin,manager,consultant', +	), +);
\ No newline at end of file diff --git a/framework/Data/ActiveRecord/TActiveRecordConfig.php b/framework/Data/ActiveRecord/TActiveRecordConfig.php index fb57fd33..51278fc9 100644 --- a/framework/Data/ActiveRecord/TActiveRecordConfig.php +++ b/framework/Data/ActiveRecord/TActiveRecordConfig.php @@ -134,4 +134,4 @@ class TActiveRecordConfig extends TDataSourceConfig  	{
  		$this->_invalidFinderResult = TPropertyValue::ensureEnum($value, 'TActiveRecordInvalidFinderResult');
  	}
 -}
\ No newline at end of file +}
 diff --git a/framework/Data/TDataSourceConfig.php b/framework/Data/TDataSourceConfig.php index 53a5ef22..cf1f963c 100644 --- a/framework/Data/TDataSourceConfig.php +++ b/framework/Data/TDataSourceConfig.php @@ -58,11 +58,23 @@ class TDataSourceConfig extends TModule  	 */
  	public function init($xml)
  	{
 -		if($prop=$xml->getElementByTagName('database'))
 +		if($this->getApplication()->getConfigurationType()==TApplication::CONFIG_TYPE_PHP)
  		{
 -			$db=$this->getDbConnection();
 -			foreach($prop->getAttributes() as $name=>$value)
 -				$db->setSubproperty($name,$value);
 +			if(isset($xml['database']) && is_array($xml['database']))
 +			{
 +				$db=$this->getDbConnection();
 +				foreach($xml['database'] as $name=>$value)
 +					$db->setSubProperty($name,$value);
 +			}
 +		}
 +		else
 +		{
 +			if($prop=$xml->getElementByTagName('database'))
 +			{
 +				$db=$this->getDbConnection();
 +				foreach($prop->getAttributes() as $name=>$value)
 +					$db->setSubproperty($name,$value);
 +			}
  		}
  	}
 @@ -153,4 +165,3 @@ class TDataSourceConfig extends TModule  			throw new TConfigurationException('datasource_dbconnection_invalid',$id);
  	}
  }
 -
 diff --git a/framework/Exceptions/messages/messages.txt b/framework/Exceptions/messages/messages.txt index fc2b63f1..ee5fc317 100644 --- a/framework/Exceptions/messages/messages.txt +++ b/framework/Exceptions/messages/messages.txt @@ -24,7 +24,7 @@ map_item_unremovable					= The item cannot be removed from the map.  map_data_not_iterable					= Data must be either an array or an object implementing Traversable interface.  map_readonly							= {0} is read-only. -application_includefile_invalid			= Unable to find application configuration {0}. Make sure it is in namespace format and the file ends with ".xml". +application_includefile_invalid			= Unable to find application configuration {0}. Make sure it is in namespace format and the file ends with ".xml" or ".php".  application_basepath_invalid			= Application base path '{0}' does not exist or is not a directory.  application_runtimepath_invalid			= Application runtime path '{0}' does not exist or is not writable by Web server process.  application_service_invalid				= Service '{0}' must implement IService interface. @@ -114,7 +114,7 @@ pageservice_page_required				= Page Name Required  pageservice_defaultpage_unchangeable	= TPageService.DefaultPage cannot be modified after the service is initialized.  pageservice_basepath_unchangeable		= TPageService.BasePath cannot be modified after the service is initialized.  pageservice_pageclass_invalid			= Page class {0} is invalid. It should be TPage or extend from TPage. -pageservice_includefile_invalid			= Unable to find page service configuration {0}. Make sure it is in namespace format and the file ends with ".xml". +pageservice_includefile_invalid			= Unable to find page service configuration {0}. Make sure it is in namespace format and the file ends with ".xml" or ".php".  pageserviceconf_file_invalid			= Unable to open page directory configuration file '{0}'.  pageserviceconf_aliaspath_invalid		= <alias id="{0}"> uses an invalid file path "{1}" in page directory configuration file '{2}'. @@ -315,7 +315,7 @@ htmlarea_textmode_readonly				= THtmlArea.TextMode is read-only.  htmlarea_tarfile_invalid				= THtmlArea is unable to locate the TinyMCE tar file.  parametermodule_parameterfile_unchangeable = TParameterModule.ParameterFile is not changeable because the module is already initialized. -parametermodule_parameterfile_invalid	= TParameterModule.ParameterFile '{0}' is invalid. Make sure it is in namespace format and the file extension is '.xml'. +parametermodule_parameterfile_invalid	= TParameterModule.ParameterFile '{0}' is invalid. Make sure it is in namespace format and the file extension is '.xml' or '.php'.  parametermodule_parameterid_required	= Parameter element must have 'id' attribute.  datagridcolumn_id_invalid				= {0}.ID '{1}' is invalid. Only alphanumeric and underline characters are allowed. The first character must be an alphabetic or underline character. @@ -401,7 +401,7 @@ dbtablegateway_invalid_table_info		= Table must be a string or an instance of TD  directorycachedependency_directory_invalid = TDirectoryCacheDependency.Directory {0} does not refer to a valid directory.  cachedependencylist_cachedependency_required = Only objects implementing ICacheDependency can be added into TCacheDependencyList. -soapservice_configfile_invalid			= TSoapService.ConfigFile '{0}' does not exist. Note, it has to be specified in a namespace format and the file extension must be '.xml'. +soapservice_configfile_invalid			= TSoapService.ConfigFile '{0}' does not exist. Note, it has to be specified in a namespace format and the file extension must be '.xml' or '.php'.  soapservice_request_invalid				= SOAP server '{0}' not found.  soapservice_serverid_required			= <soap> element must have 'id' attribute.  soapservice_serverid_duplicated			= SOAP server ID '{0}' is duplicated. diff --git a/framework/I18N/TGlobalization.php b/framework/I18N/TGlobalization.php index fd16f7bd..2201f4e5 100644 --- a/framework/I18N/TGlobalization.php +++ b/framework/I18N/TGlobalization.php @@ -62,20 +62,26 @@ class TGlobalization extends TModule  	 * You should override this method if you want a different way of
  	 * setting the Culture and/or Charset for your application.
  	 * If you override this method, call parent::init($xml) first.
 -	 * @param TXmlElement application configuration
 +	 * @param mixed application configuration
  	 */
 -	public function init($xml)
 +	public function init($config)
  	{
  		if($this->_charset===null)
  			$this->_charset=$this->getDefaultCharset();
  		if($this->_culture===null)
  			$this->_culture=$this->getDefaultCulture();
 -		if($xml!==null)
 +		if($config!==null)
  		{
 -			$translation = $xml->getElementByTagName('translation');
 +			if($this->getApplication()->getConfigurationType()==TApplication::CONFIG_TYPE_PHP)
 +				$translation = isset($config['translate'])?$config['translate']:null;
 +			else
 +			{
 +				$t = $config->getElementByTagName('translation');
 +				$translation = ($t)?$t->getAttributes():null;
 +			}
  			if($translation)
 -				$this->setTranslationConfiguration($translation->getAttributes());
 +				$this->setTranslationConfiguration($translation);
  		}
  		$this->getApplication()->setGlobalization($this);
  	}
 @@ -165,9 +171,9 @@ class TGlobalization extends TModule  	 * $config['marker'] = '@@'; // surround untranslated text with '@@'
  	 * </code>
  	 * Throws exception is source is not found.
 -	 * @param TMap configuration options
 +	 * @param TMap|array configuration options
  	 */
 -	protected function setTranslationConfiguration(TMap $config)
 +	protected function setTranslationConfiguration($config)
  	{
  		if($config['type'] == 'XLIFF' || $config['type'] == 'gettext')
  		{
 diff --git a/framework/PradoBase.php b/framework/PradoBase.php index a08b54ba..084dd62b 100644 --- a/framework/PradoBase.php +++ b/framework/PradoBase.php @@ -66,7 +66,7 @@ class PradoBase  	 */  	public static function getVersion()  	{ -		return '3.1.6-dev'; +		return '3.2-dev';
  	}  	/** diff --git a/framework/Security/TUserManager.php b/framework/Security/TUserManager.php index bfade687..1a99bfcb 100644 --- a/framework/Security/TUserManager.php +++ b/framework/Security/TUserManager.php @@ -29,6 +29,26 @@ Prado::using('System.Security.TUser');   * </module>
   * </code>
   *
 + * PHP configuration style:
 + * <code>
 + * array(
 + *   'users' => array(
 + *      'class' => 'System.Security.TUserManager',
 + *      'properties' => array(
 + *         'PasswordMode' => 'Clear',
 + *       ),
 + *       'users' => array(
 + *          array('name'=>'Joe','password'=>'demo'),
 + *          array('name'=>'John','password'=>'demo'),
 + *       ),
 + *       'roles' => array(
 + *          array('name'=>'Administrator','users'=>'John'),
 + *          array('name'=>'Writer','users'=>'Joe,John'),
 + *       ),
 + *    ),
 + * )
 + * </code>
 + *
   * In addition, user information can also be loaded from an external file
   * specified by {@link setUserFile UserFile} property. Note, the property
   * only accepts a file path in namespace format. The user file format is
 @@ -43,6 +63,7 @@ Prado::using('System.Security.TUser');   * how users are authenticated and authorized in a Prado application.
   *
   * @author Qiang Xue <qiang.xue@gmail.com>
 + * @author Carl Mathisen <carl@kamikazemedia.no>
   * @version $Id$
   * @package System.Security
   * @since 3.0
 @@ -83,25 +104,84 @@ class TUserManager extends TModule implements IUserManager  	 * Initializes the module.
  	 * This method is required by IModule and is invoked by application.
  	 * It loads user/role information from the module configuration.
 -	 * @param TXmlElement module configuration
 +	 * @param mixed module configuration
  	 */
  	public function init($config)
  	{
 -		$this->loadUserData($config);
 +		$this->loadUserData($config);	
  		if($this->_userFile!==null)
  		{
 -			$dom=new TXmlDocument;
 -			$dom->loadFromFile($this->_userFile);
 -			$this->loadUserData($dom);
 +			if($this->getApplication()->getConfigurationType()==TApplication::CONFIG_TYPE_PHP)
 +			{
 +				$userFile = include $this->_userFile;
 +				$this->loadUserDataFromPhp($userFile);
 +			}
 +			else
 +			{
 +				$dom=new TXmlDocument;
 +				$dom->loadFromFile($this->_userFile);
 +				$this->loadUserDataFromXml($dom);
 +			}
  		}
  		$this->_initialized=true;
  	}
 +	
 +	/*
 +	 * Loads user/role information
 +	 * @param mixed the variable containing the user information
 +	 */
 +	private function loadUserData($config)
 +	{
 +		if($this->getApplication()->getConfigurationType()==TApplication::CONFIG_TYPE_PHP)
 +			$this->loadUserDataFromPhp($config);
 +		else
 +			$this->loadUserDataFromXml($config);
 +	}
 +
 +	/**
 +	 * Loads user/role information from an php array.
 +	 * @param array the array containing the user information
 +	 */
 +	private function loadUserDataFromPhp($config)
 +	{
 +		if(isset($config['users']) && is_array($config['users']))
 +		{
 +			foreach($config['users'] as $user)
 +			{
 +				$name = trim(strtolower(isset($user['name'])?$user['name']:''));
 +				$password = isset($user['password'])?$user['password']:'';
 +				$this->_users[$name] = $password;
 +				$roles = isset($user['roles'])?$user['roles']:'';
 +				if($roles!=='')
 +				{
 +					foreach(explode(',',$roles) as $role)
 +					{
 +						if(($role=trim($role))!=='')
 +							$this->_roles[$name][]=$role;
 +					}
 +				}
 +			}
 +		}
 +		if(isset($config['roles']) && is_array($config['roles']))
 +		{
 +			foreach($config['roles'] as $role)
 +			{
 +				$name = isset($role['name'])?$role['name']:'';
 +				$users = isset($role['users'])?$role['users']:'';
 +				foreach(explode(',',$users) as $user)
 +				{
 +					if(($user=trim($user))!=='')
 +						$this->_roles[strtolower($user)][]=$name;
 +				}
 +			}
 +		}
 +	}
  	/**
  	 * Loads user/role information from an XML node.
  	 * @param TXmlElement the XML node containing the user information
  	 */
 -	protected function loadUserData($xmlNode)
 +	private function loadUserDataFromXml($xmlNode)
  	{
  		foreach($xmlNode->getElementsByTagName('user') as $node)
  		{
 diff --git a/framework/TApplication.php b/framework/TApplication.php index 1901506b..d9298d90 100644 --- a/framework/TApplication.php +++ b/framework/TApplication.php @@ -127,11 +127,27 @@ class TApplication extends TComponent  	/**  	 * Application configuration file name  	 */ -	const CONFIG_FILE='application.xml'; +	const CONFIG_FILE_XML='application.xml';  	/**  	 * File extension for external config files  	 */ -	const CONFIG_FILE_EXT='.xml'; +	const CONFIG_FILE_EXT_XML='.xml';	 +	/** +	 * Configuration file type, application.xml and config.xml +	 */ +	const CONFIG_TYPE_XML = 'xml'; +	/** +	 * Application configuration file name +	 */ +	const CONFIG_FILE_PHP='application.php'; +	/** +	 * File extension for external config files +	 */ +	const CONFIG_FILE_EXT_PHP='.php'; +	/** +	 * Configuration file type, application.php and config.php +	 */ +	const CONFIG_TYPE_PHP = 'php';  	/**  	 * Runtime directory name  	 */ @@ -201,6 +217,14 @@ class TApplication extends TComponent  	 */  	private $_configFile;  	/** +	 * @var string configuration file extension +	 */ +	private $_configFileExt; +	/** +	 * @var string configuration type +	 */ +	private $_configType; +	/**  	 * @var string application base path  	 */  	private $_basePath; @@ -292,11 +316,11 @@ class TApplication extends TComponent  	 * @param boolean whether to cache application configuration. Defaults to true.  	 * @throws TConfigurationException if configuration file cannot be read or the runtime path is invalid.  	 */ -	public function __construct($basePath='protected',$cacheConfig=true) +	public function __construct($basePath='protected',$cacheConfig=true, $configType=self::CONFIG_TYPE_XML)  	{  		// register application as a singleton  		Prado::setApplication($this); - +		$this->setConfigurationType($configType);  		$this->resolvePaths($basePath);  		if($cacheConfig) @@ -325,8 +349,8 @@ class TApplication extends TComponent  		// determine configuration path and file  		if(empty($basePath) || ($basePath=realpath($basePath))===false)  			throw new TConfigurationException('application_basepath_invalid',$basePath); -		if(is_file($basePath.DIRECTORY_SEPARATOR.self::CONFIG_FILE)) -			$configFile=$basePath.DIRECTORY_SEPARATOR.self::CONFIG_FILE; +		if(is_file($basePath.DIRECTORY_SEPARATOR.$this->getConfigurationFileName())) +			$configFile=$basePath.DIRECTORY_SEPARATOR.$this->getConfigurationFileName();  		else if(is_file($basePath))  		{  			$configFile=$basePath; @@ -564,6 +588,61 @@ class TApplication extends TComponent  	}  	/** +	 * @return string the application configuration file (absolute path) +	 */ +	public function getConfigurationType() +	{ +		return $this->_configType; +	} + + 	/** + 	 * @param string the application configuration type. 'xml' and 'php' are valid values +	 */ +	public function setConfigurationType($value) +	{ +		$this->_configType = $value; +	} +	 +	/** +	 * @return string the applictaion configuration type. default is 'xml' +	 */ +	public function getConfigurationFileExt() +	{ +		if($this->_configFileExt===null) +		{ +			switch($this->_configType) +			{ +				case TApplication::CONFIG_TYPE_PHP: +					$this->_configFileExt = TApplication::CONFIG_FILE_EXT_PHP; +					break; +				default: +					$this->_configFileExt = TApplication::CONFIG_FILE_EXT_XML; +			} +		} +		return $this->_configFileExt; +	} +	 +	/** +	 * @return string the default configuration file name +	 */ +	public function getConfigurationFileName() +	{ +		static $fileName; +		if($fileName == null) +		{ +			switch($this->_configType) +			{ +				case TApplication::CONFIG_TYPE_PHP: +					$fileName = TApplication::CONFIG_FILE_PHP; +					break; +				default: +					$fileName = TApplication::CONFIG_FILE_XML; +			} +		} +		return $fileName; +	} + +	/**  	 * @return string the directory storing cache data and application-level persistent data. (absolute path)  	 */  	public function getRuntimePath() @@ -919,7 +998,7 @@ class TApplication extends TComponent  				$condition=$this->evaluateExpression($condition);  			if($condition)  			{ -				if(($path=Prado::getPathOfNamespace($filePath,self::CONFIG_FILE_EXT))===null || !is_file($path)) +				if(($path=Prado::getPathOfNamespace($filePath,$this->getConfigurationFileExt()))===null || !is_file($path))  					throw new TConfigurationException('application_includefile_invalid',$filePath);  				$c=new TApplicationConfiguration;  				$c->loadFromFile($path); @@ -987,7 +1066,10 @@ class TApplication extends TComponent  			if($configElement!==null)  			{  				$config=new TApplicationConfiguration; -				$config->loadFromXml($configElement,$this->getBasePath()); +				if($this->getConfigurationType()==self::CONFIG_TYPE_PHP) +					$config->loadFromPhp($configElement,$this->getBasePath()); +				else +					$config->loadFromXml($configElement,$this->getBasePath());  				$this->applyConfiguration($config,true);  			} @@ -1171,6 +1253,7 @@ class TApplicationMode extends TEnumerable   * This class is used internally by TApplication to parse and represent application configuration.   *   * @author Qiang Xue <qiang.xue@gmail.com> + * @author Carl G. Mathisen <carlgmathisen@gmail.com>   * @version $Id$   * @package System   * @since 3.0 @@ -1217,9 +1300,17 @@ class TApplicationConfiguration extends TComponent  	 */  	public function loadFromFile($fname)  	{ -		$dom=new TXmlDocument; -		$dom->loadFromFile($fname); -		$this->loadFromXml($dom,dirname($fname)); +		if(Prado::getApplication()->getConfigurationType()==TApplication::CONFIG_TYPE_PHP) +		{ +			$fcontent = include $fname; +			$this->loadFromPhp($fcontent,dirname($fname)); +		} +		else +		{ +			$dom=new TXmlDocument; +			$dom->loadFromFile($fname); +			$this->loadFromXml($dom,dirname($fname)); +		}  	}  	/** @@ -1231,6 +1322,39 @@ class TApplicationConfiguration extends TComponent  	}  	/** +	 * Parses the application configuration given in terms of a PHP array. +	 * @param array the PHP array +	 * @param string the context path (for specifying relative paths) +	 */ +	public function loadFromPhp($config, $configPath) +	{ +		// application properties +		if(isset($config['application'])) +		{ +			foreach($config['application'] as $name=>$value) +			{ +				$this->_properties[$name]=$value; +			} +			$this->_empty = false; +		}	 + +		if(isset($config['paths']) && is_array($config['paths'])) +			$this->loadPathsPhp($config['paths'],$configPath); + +		if(isset($config['modules']) && is_array($config['modules'])) +			$this->loadModulesPhp($config['modules'],$configPath); + +		if(isset($config['services']) && is_array($config['services'])) +			$this->loadServicesPhp($config['services'],$configPath); + +		if(isset($config['parameters']) && is_array($config['parameters'])) +			$this->loadParametersPhp($config['parameters'], $configPath); +		 +		if(isset($config['includes']) && is_array($config['includes'])) +			$this->loadExternalXml($config['includes'],$configPath); +	} + +	/**  	 * Parses the application configuration given in terms of a TXmlElement.  	 * @param TXmlElement the XML element  	 * @param string the context path (for specifying relative paths) @@ -1271,6 +1395,39 @@ class TApplicationConfiguration extends TComponent  	}  	/** +	 * Loads the paths PHP array +	 * @param array the paths PHP array +	 * @param string the context path (for specifying relative paths) +	 */ +	protected function loadPathsPhp($pathsNode, $configPath) +	{ +		if(isset($pathsNode['aliases']) && is_array($pathsNode['aliases'])) +		{ +			foreach($pathsNode['aliases'] as $id=>$path) +			{ +				$path=str_replace('\\','/',$path); +				if(preg_match('/^\\/|.:\\/|.:\\\\/',$path))	// if absolute path +					$p=realpath($path); +				else +					$p=realpath($configPath.DIRECTORY_SEPARATOR.$path); +				if($p===false || !is_dir($p)) +					throw new TConfigurationException('appconfig_aliaspath_invalid',$id,$path); +				if(isset($this->_aliases[$id])) +					throw new TConfigurationException('appconfig_alias_redefined',$id); +				$this->_aliases[$id]=$p; +			} +		} + +		if(isset($pathsNode['using']) && is_array($pathsNode['using'])) +		{ +			foreach($pathsNode['using'] as $namespace) +			{ +				$this->_usings[] = $namespace; +			} +		} +	} + +	/**  	 * Loads the paths XML node.  	 * @param TXmlElement the paths XML node  	 * @param string the context path (for specifying relative paths) @@ -1317,6 +1474,31 @@ class TApplicationConfiguration extends TComponent  	}  	/** +	 * Loads the modules PHP array. +	 * @param array the modules PHP array +	 * @param string the context path (for specifying relative paths) +	 */ +	protected function loadModulesPhp($modulesNode, $configPath) +	{ +		foreach($modulesNode as $id=>$module) +		{ +			if(!isset($module['class'])) +				throw new TConfigurationException('appconfig_moduletype_required',$id); +			$type = $module['class']; +			unset($module['class']); +			$properties = array(); +			if(isset($module['properties'])) +			{ +				$properties = $module['properties']; +				unset($module['properties']); +			} +			$properties['id'] = $id; +			$this->_modules[$id]=array($type,$properties,$module); +			$this->_empty=false; +		}	 +	} + +	/**  	 * Loads the modules XML node.  	 * @param TXmlElement the modules XML node  	 * @param string the context path (for specifying relative paths) @@ -1345,6 +1527,26 @@ class TApplicationConfiguration extends TComponent  	}  	/** +	 * Loads the services PHP array. +	 * @param array the services PHP array +	 * @param string the context path (for specifying relative paths) +	 */ +	protected function loadServicesPhp($servicesNode,$configPath) +	{ +		foreach($servicesNode as $id => $service) +		{ +			if(!isset($service['class'])) +				throw new TConfigurationException('appconfig_servicetype_required'); +			$type = $service['class']; +			$properties = isset($service['properties']) ? $service['properties'] : array(); +			unset($service['properties']); +			$properties['id'] = $id; +			$this->_services[$id] = array($type,$properties,$service); +			$this->_empty = false; +		}	 +	} + +	/**  	 * Loads the services XML node.  	 * @param TXmlElement the services XML node  	 * @param string the context path (for specifying relative paths) @@ -1370,6 +1572,33 @@ class TApplicationConfiguration extends TComponent  	}  	/** +	 * Loads the parameters PHP array. +	 * @param array the parameters PHP array +	 * @param string the context path (for specifying relative paths) +	 */ +	protected function loadParametersPhp($parametersNode,$configPath) +	{ +		foreach($parametersNode as $id => $parameter) +		{ +			if(is_array($parameter)) +			{ +				if(isset($parameter['class'])) +				{ +					$type = $parameter['class']; +					unset($parameter['class']); +					$properties = isset($service['properties']) ? $service['properties'] : array(); +					$properties['id'] = $id; +					$this->_parameters[$id] = array($type,$properties); +				} +			} +			else +			{ +				$this->_parameters[$id] = $parameter; +			} +		} +	} + +	/**  	 * Loads the parameters XML node.  	 * @param TXmlElement the parameters XML node  	 * @param string the context path (for specifying relative paths) @@ -1400,6 +1629,27 @@ class TApplicationConfiguration extends TComponent  	}  	/** +	 * Loads the external PHP array. +	 * @param array the application PHP array +	 * @param string the context path (for specifying relative paths) +	 */ +	protected function loadExternalPhp($includeNode,$configPath) +	{ +		foreach($includeNode as $include) +		{ +			$when = isset($include['when'])?true:false; +			if(!isset($include['file'])) +				throw new TConfigurationException('appconfig_includefile_required'); +			$filePath = $include['file']; +			if(isset($this->_includes[$filePath])) +				$this->_includes[$filePath]='('.$this->_includes[$filePath].') || ('.$when.')'; +			else +				$$this->_includes[$filePath]=$when; +			$this->_empty=false; +		} +	} + +	/**  	 * Loads the external XML configurations.  	 * @param TXmlElement the application DOM element  	 * @param string the context path (for specifying relative paths) diff --git a/framework/Util/TLogRouter.php b/framework/Util/TLogRouter.php index 64a241fb..a8f42b56 100644 --- a/framework/Util/TLogRouter.php +++ b/framework/Util/TLogRouter.php @@ -27,10 +27,15 @@ Prado::using('System.Data.TDbConnection');   *   <route class="TFileLogRoute" Categories="System.Web.UI" Levels="Warning" />
   *   <route class="TEmailLogRoute" Categories="Application" Levels="Fatal" Emails="admin@pradosoft.com" />
   * </code>
 + * PHP configuration style:
 + * <code>
 + * 
 + * </code>
   * You can specify multiple routes with different filtering conditions and different
   * targets, even if the routes are of the same type.
   *
   * @author Qiang Xue <qiang.xue@gmail.com>
 + * @author Carl G. Mathisen <carlgmathisen@gmail.com>
   * @version $Id$
   * @package System.Util
   * @since 3.0
 @@ -38,10 +43,6 @@ Prado::using('System.Data.TDbConnection');  class TLogRouter extends TModule
  {
  	/**
 -	 * File extension of external configuration file
 -	 */
 -	const CONFIG_FILE_EXT='.xml';
 -	/**
  	 * @var array list of routes available
  	 */
  	private $_routes=array();
 @@ -53,7 +54,7 @@ class TLogRouter extends TModule  	/**
  	 * Initializes this module.
  	 * This method is required by the IModule interface.
 -	 * @param TXmlElement configuration for this module, can be null
 +	 * @param mixed configuration for this module, can be null
  	 * @throws TConfigurationException if {@link getConfigFile ConfigFile} is invalid.
  	 */
  	public function init($config)
 @@ -62,9 +63,17 @@ class TLogRouter extends TModule  		{
   			if(is_file($this->_configFile))
   			{
 -				$dom=new TXmlDocument;
 -				$dom->loadFromFile($this->_configFile);
 -				$this->loadConfig($dom);
 +				if($this->getApplication()->getConfigurationType()==TApplication::CONFIG_TYPE_PHP)
 +				{
 +					$phpConfig = include $this->_configFile;
 +					$this->loadConfig($phpConfig);
 +				}
 +				else
 +				{
 +					$dom=new TXmlDocument;
 +					$dom->loadFromFile($this->_configFile);
 +					$this->loadConfig($dom);
 +				}
  			}
  			else
  				throw new TConfigurationException('logrouter_configfile_invalid',$this->_configFile);
 @@ -74,31 +83,53 @@ class TLogRouter extends TModule  	}
  	/**
 -	 * Loads configuration from an XML element
 -	 * @param TXmlElement configuration node
 +	 * Loads configuration from an XML element or PHP array
 +	 * @param mixed configuration node
  	 * @throws TConfigurationException if log route class or type is not specified
  	 */
 -	private function loadConfig($xml)
 +	private function loadConfig($config)
  	{
 -		foreach($xml->getElementsByTagName('route') as $routeConfig)
 +		if(is_array($config))
  		{
 -			$properties=$routeConfig->getAttributes();
 -			if(($class=$properties->remove('class'))===null)
 -				throw new TConfigurationException('logrouter_routeclass_required');
 -			$route=Prado::createComponent($class);
 -			if(!($route instanceof TLogRoute))
 -				throw new TConfigurationException('logrouter_routetype_invalid');
 -			foreach($properties as $name=>$value)
 -				$route->setSubproperty($name,$value);
 -			$this->_routes[]=$route;
 -			$route->init($routeConfig);
 +			if(isset($config['routes']) && is_array($config['routes']))
 +			{
 +				foreach($config['routes'] as $route)
 +				{
 +					$properties = isset($route['properties'])?$route['properties']:array();
 +					if(!isset($route['class']))
 +						throw new TConfigurationException('logrouter_routeclass_required');
 +					$route=Prado::createComponent($route['class']);
 +					if(!($route instanceof TLogRoute))
 +						throw new TConfigurationException('logrouter_routetype_invalid');
 +					foreach($properties as $name=>$value)
 +						$route->setSubproperty($name,$value);
 +					$this->_routes[]=$route;
 +					$route->init($route);
 +				}
 +			}
 +		}
 +		else
 +		{
 +			foreach($config->getElementsByTagName('route') as $routeConfig)
 +			{
 +				$properties=$routeConfig->getAttributes();
 +				if(($class=$properties->remove('class'))===null)
 +					throw new TConfigurationException('logrouter_routeclass_required');
 +				$route=Prado::createComponent($class);
 +				if(!($route instanceof TLogRoute))
 +					throw new TConfigurationException('logrouter_routetype_invalid');
 +				foreach($properties as $name=>$value)
 +					$route->setSubproperty($name,$value);
 +				$this->_routes[]=$route;
 +				$route->init($routeConfig);
 +			}
  		}
  	}
  	/**
  	 * Adds a TLogRoute instance to the log router.
 -	 *
 -	 * @param TLogRoute $route
 +	 * 
 +	 * @param TLogRoute $route 
  	 * @throws TInvalidDataTypeException if the route object is invalid
  	 */
  	public function addRoute($route)
 @@ -124,7 +155,7 @@ class TLogRouter extends TModule  	 */
  	public function setConfigFile($value)
  	{
 -		if(($this->_configFile=Prado::getPathOfNamespace($value,self::CONFIG_FILE_EXT))===null)
 +		if(($this->_configFile=Prado::getPathOfNamespace($value,$this->getApplication()->getConfigurationFileExt()))===null)
  			throw new TConfigurationException('logrouter_configfile_invalid',$value);
  	}
 diff --git a/framework/Util/TParameterModule.php b/framework/Util/TParameterModule.php index 529f20ca..0109ca32 100644 --- a/framework/Util/TParameterModule.php +++ b/framework/Util/TParameterModule.php @@ -4,7 +4,7 @@   *
   * @author Qiang Xue <qiang.xue@gmail.com>
   * @link http://www.pradosoft.com/
 - * @copyright Copyright © 2005-2008 PradoSoft + * @copyright Copyright © 2005-2008 PradoSoft
   * @license http://www.pradosoft.com/license/
   * @version $Id$
   * @package System.Util
 @@ -40,67 +40,97 @@   * tag, the former takes precedence.
   *
   * @author Qiang Xue <qiang.xue@gmail.com>
 + * @author Carl G. Mathisen <carlgmathisen@gmail.com>
   * @version $Id$
   * @package System.Util
   * @since 3.0
   */
  class TParameterModule extends TModule
  {
 +	/**
 +	 * @deprecated since 3.2
 +	 */
  	const PARAM_FILE_EXT='.xml';
  	private $_initialized=false;
  	private $_paramFile=null;
  	/**
  	 * Initializes the module by loading parameters.
 -	 * @param TXmlElement content enclosed within the module tag
 +	 * @param mixed content enclosed within the module tag
  	 */
  	public function init($config)
  	{
  		$this->loadParameters($config);
  		if($this->_paramFile!==null)
  		{
 -			if(($cache=$this->getApplication()->getCache())!==null)
 +			$configFile = null;
 +			if($this->getApplication()->getConfigurationType()==TApplication::CONFIG_TYPE_XML && ($cache=$this->getApplication()->getCache())!==null)
  			{
  				$cacheKey='TParameterModule:'.$this->_paramFile;
 -				if(($dom=$cache->get($cacheKey))===false)
 +				if(($configFile=$cache->get($cacheKey))===false)
  				{
 -					$dom=new TXmlDocument;
 -					$dom->loadFromFile($this->_paramFile);
 -					$cache->set($cacheKey,$dom,0,new TFileCacheDependency($this->_paramFile));
 +					$cacheFile=new TXmlDocument;
 +					$cacheFile->loadFromFile($this->_paramFile);
 +					$cache->set($cacheKey,$cacheFile,0,new TFileCacheDependency($this->_paramFile));
  				}
  			}
  			else
  			{
 -				$dom=new TXmlDocument;
 -				$dom->loadFromFile($this->_paramFile);
 +				if($this->getApplication()->getConfigurationType()==TApplication::CONFIG_TYPE_PHP)
 +				{
 +					$configFile = include $this->_paramFile;
 +				}
 +				else
 +				{
 +					$configFile=new TXmlDocument;
 +					$configFile->loadFromFile($this->_paramFile);
 +				}
  			}
 -			$this->loadParameters($dom);
 +			$this->loadParameters($configFile);
  		}
  		$this->_initialized=true;
  	}
  	/**
  	 * Loads parameters into application.
 -	 * @param TXmlElement XML representation of the parameters
 +	 * @param mixed XML of PHP representation of the parameters
  	 * @throws TConfigurationException if the parameter file format is invalid
  	 */
 -	protected function loadParameters($xmlNode)
 +	protected function loadParameters($config)
  	{
  		$parameters=array();
 -		foreach($xmlNode->getElementsByTagName('parameter') as $node)
 +		if(is_array($config))
  		{
 -			$properties=$node->getAttributes();
 -			if(($id=$properties->remove('id'))===null)
 -				throw new TConfigurationException('parametermodule_parameterid_required');
 -			if(($type=$properties->remove('class'))===null)
 +			foreach($config as $id => $parameter)
  			{
 -				if(($value=$properties->remove('value'))===null)
 -					$parameters[$id]=$node;
 +				if(is_array($parameter) && isset($parameter['class']))
 +				{
 +					$properties = isset($parameter['properties'])?$parameter['properties']:array();
 +					$parameters[$id]=array($parameter['class'],$properties);
 +				}
  				else
 -					$parameters[$id]=$value;
 +				{
 +					$parameters[$id] = $parameter;
 +				}
 +			}
 +		}
 +		else if($config instanceof TXmlElement)
 +		{
 +			foreach($config->getElementsByTagName('parameter') as $node)
 +			{
 +				$properties=$node->getAttributes();
 +				if(($id=$properties->remove('id'))===null)
 +					throw new TConfigurationException('parametermodule_parameterid_required');
 +				if(($type=$properties->remove('class'))===null)
 +				{
 +					if(($value=$properties->remove('value'))===null)
 +						$parameters[$id]=$node;
 +					else
 +						$parameters[$id]=$value;
 +				}
 +				else
 +					$parameters[$id]=array($type,$properties->toArray());
  			}
 -			else
 -				$parameters[$id]=array($type,$properties->toArray());
  		}
  		$appParams=$this->getApplication()->getParameters();
 @@ -136,7 +166,7 @@ class TParameterModule extends TModule  	{
  		if($this->_initialized)
  			throw new TInvalidOperationException('parametermodule_parameterfile_unchangeable');
 -		else if(($this->_paramFile=Prado::getPathOfNamespace($value,self::PARAM_FILE_EXT))===null || !is_file($this->_paramFile))
 +		else if(($this->_paramFile=Prado::getPathOfNamespace($value,$this->getApplication()->getConfigurationFileExt()))===null || !is_file($this->_paramFile))
  			throw new TConfigurationException('parametermodule_parameterfile_invalid',$value);
  	}
  }
 diff --git a/framework/Web/Services/TFeedService.php b/framework/Web/Services/TFeedService.php index 7ecd10a7..d4afbade 100644 --- a/framework/Web/Services/TFeedService.php +++ b/framework/Web/Services/TFeedService.php @@ -5,7 +5,7 @@   * @author Qiang Xue <qiang.xue@gmail.com>
   * @author Knut Urdalen <knut.urdalen@gmail.com>
   * @link http://www.pradosoft.com
 - * @copyright Copyright © 2005-2008 PradoSoft + * @copyright Copyright © 2005-2008 PradoSoft
   * @license http://www.pradosoft.com/license/
   * @version $Id$
   * @package System.Web.Services
 @@ -28,6 +28,20 @@   *  </service>
   * </code>
   * where each <feed> element specifies a feed identified by its "id" value (case-sensitive).
 + *
 + * PHP configuration style:
 + * <code>
 + * array(
 + *   'feed' => array(
 + *	   'ch1' => array(
 + *       'class' => 'Path.To.FeedClass1',
 + *       'properties' => array(
 + *          ...
 + *        ),
 + *   ),
 + * )
 + * </code>
 + *
   * The class attribute indicates which PHP class will provide the actual feed
   * content. Note, the class must implement {@link IFeedContentProvider} interface.
   * Other initial properties for the feed class may also be specified in the
 @@ -38,6 +52,7 @@   *
   * @author Qiang Xue <qiang.xue@gmail.com>
   * @author Knut Urdalen <knut.urdalen@gmail.com>
 + * @author Carl G. Mathisen <carlgmathisen@gmail.com>
   * @package System.Web.Services
   * @since 3.1
   */
 @@ -48,16 +63,27 @@ class TFeedService extends TService  	/**
  	 * Initializes this module.
  	 * This method is required by the IModule interface.
 -	 * @param TXmlElement configuration for this module, can be null
 +	 * @param mixed configuration for this module, can be null
  	 */
  	public function init($config)
  	{
 -		foreach($config->getElementsByTagName('feed') as $feed)
 +		if($this->getApplication()->getConfigurationType()==TApplication::CONFIG_TYPE_PHP)
  		{
 -			if(($id=$feed->getAttributes()->remove('id'))!==null)
 -				$this->_feeds[$id]=$feed;
 -			else
 -				throw new TConfigurationException('feedservice_id_required');
 +			if(is_array($config))
 +			{
 +				foreach($config as $id => $feed)
 +					$this->_feeds[$id] = $feed;
 +			}
 +		}
 +		else
 +		{
 +			foreach($config->getElementsByTagName('feed') as $feed)
 +			{
 +				if(($id=$feed->getAttributes()->remove('id'))!==null)
 +					$this->_feeds[$id]=$feed;
 +				else
 +					throw new TConfigurationException('feedservice_id_required');
 +			}
  		}
  	}
 @@ -79,27 +105,43 @@ class TFeedService extends TService  		if(isset($this->_feeds[$id]))
  		{
  			$feedConfig=$this->_feeds[$id];
 -			$properties=$feedConfig->getAttributes();
 -			if(($class=$properties->remove('class'))!==null)
 +			$properties = array();
 +			$feed = null;
 +			if($this->getApplication()->getConfigurationType()==TApplication::CONFIG_TYPE_PHP)
  			{
 -				$feed=Prado::createComponent($class);
 -				if($feed instanceof IFeedContentProvider)
 +				if(isset($feedConfig['class']))
  				{
 -					// init feed properties
 -					foreach($properties as $name=>$value)
 -						$feed->setSubproperty($name,$value);
 -					$feed->init($feedConfig);
 -
 -					$content=$feed->getFeedContent();
 -				    //$this->getResponse()->setContentType('application/rss+xml');
 -				    $this->getResponse()->setContentType($feed->getContentType());
 -				    $this->getResponse()->write($content);
 +					$feed=Prado::createComponent($feedConfig['class']);
 +					if($service instanceof IFeedContentProvider)
 +						$properties=isset($feedConfig['properties'])?$feedConfig['properties']:array();
 +					else
 +						throw new TConfigurationException('jsonservice_response_type_invalid',$id);
  				}
  				else
 -					throw new TConfigurationException('feedservice_feedtype_invalid',$id);
 +					throw new TConfigurationException('jsonservice_class_required',$id);
  			}
  			else
 -				throw new TConfigurationException('feedservice_class_required',$id);
 +			{
 +				$properties=$feedConfig->getAttributes();
 +				if(($class=$properties->remove('class'))!==null)
 +				{
 +					$feed=Prado::createComponent($class);
 +					if(!($feed instanceof IFeedContentProvider))
 +						throw new TConfigurationException('feedservice_feedtype_invalid',$id);
 +				}
 +				else
 +					throw new TConfigurationException('feedservice_class_required',$id);
 +			}
 +			
 +			// init feed properties
 +			foreach($properties as $name=>$value)
 +				$feed->setSubproperty($name,$value);
 +			$feed->init($feedConfig);
 +
 +			$content=$feed->getFeedContent();
 +		    //$this->getResponse()->setContentType('application/rss+xml');
 +		    $this->getResponse()->setContentType($feed->getContentType());
 +		    $this->getResponse()->write($content);
  		}
  		else
  			throw new THttpException(404,'feedservice_feed_unknown',$id);
 diff --git a/framework/Web/Services/TJsonService.php b/framework/Web/Services/TJsonService.php index e3ed9a7f..d3a6bbf0 100644 --- a/framework/Web/Services/TJsonService.php +++ b/framework/Web/Services/TJsonService.php @@ -29,10 +29,24 @@   * where each JSON response is specified via a <json> element.
   * Initial property values can be configured in a <json> element.
   *
 + *
 + * PHP configuration style:
 + * <code>
 + *  'services' => array(
 + *    'get_article' => array(
 + *     'class' => 'Path.To.JsonResponseClass1',
 + *     'properties' => array(
 + *       ...
 + *	    )
 + *    )
 + *  )
 + * </code>
 + *
   * To retrieve the JSON content provided by "get_article", use the URL
   * <code>index.php?json=get_article</code>
   *
   * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
 + * @author Carl G. Mathisen <carlgmathisen@gmail.com>
   * @version $Id$
   * @package System.Web.Services
   * @since 3.1
 @@ -47,7 +61,7 @@ class TJsonService extends TService  	/**
  	 * Initializes this module.
  	 * This method is required by the IModule interface.
 -	 * @param TXmlElement configuration for this module, can be null
 +	 * @param mixed configuration for this module, can be null
  	 */
  	public function init($xml)
  	{
 @@ -56,16 +70,27 @@ class TJsonService extends TService  	/**
  	 * Load the service definitions.
 -	 * @param TXmlElement configuration for this module, can be null
 +	 * @param mixed configuration for this module, can be null
  	 */
 -	protected function loadJsonServices($xml)
 +	protected function loadJsonServices($config)
  	{
 -		foreach($xml->getElementsByTagName('json') as $config)
 +		if($this->getApplication()->getConfigurationType()==TApplication::CONFIG_TYPE_PHP)
  		{
 -			if(($id=$config->getAttribute('id'))!==null)
 -				$this->_services[$id]=$config;
 -			else
 -				throw new TConfigurationException('jsonservice_id_required');
 +			if(is_array($config))
 +			{
 +				foreach($config['json'] as $id => $json)
 +					$this->_services[$id] = $json;
 +			}
 +		}
 +		else
 +		{
 +			foreach($config->getElementsByTagName('json') as $json)
 +			{
 +				if(($id=$json->getAttribute('id'))!==null)
 +					$this->_services[$id]=$json;
 +				else
 +					throw new TConfigurationException('jsonservice_id_required');
 +			}
  		}
  	}
 @@ -79,17 +104,36 @@ class TJsonService extends TService  		if(isset($this->_services[$id]))
  		{
  			$serviceConfig=$this->_services[$id];
 -			$properties=$serviceConfig->getAttributes();
 -			if(($class=$properties->remove('class'))!==null)
 +			if($this->getApplication()->getConfigurationType()==TApplication::CONFIG_TYPE_PHP)
  			{
 -				$service=Prado::createComponent($class);
 -				if($service instanceof TJsonResponse)
 -					$this->createJsonResponse($service,$properties,$serviceConfig);
 +				if(isset($serviceConfig['class']))
 +				{
 +					$service=Prado::createComponent($serviceConfig['class']);
 +					if($service instanceof TJsonResponse)
 +					{
 +						$properties = isset($serviceConfig['properties'])?$serviceConfig['properties']:array();
 +						$this->createJsonResponse($service,$properties,$serviceConfig);
 +					}
 +					else
 +						throw new TConfigurationException('jsonservice_response_type_invalid',$id);
 +				}
  				else
 -					throw new TConfigurationException('jsonservice_response_type_invalid',$id);
 +					throw new TConfigurationException('jsonservice_class_required',$id);
  			}
  			else
 -				throw new TConfigurationException('jsonservice_class_required',$id);
 +			{
 +				$properties=$serviceConfig->getAttributes();
 +				if(($class=$properties->remove('class'))!==null)
 +				{
 +					$service=Prado::createComponent($class);
 +					if($service instanceof TJsonResponse)
 +						$this->createJsonResponse($service,$properties,$serviceConfig);
 +					else
 +						throw new TConfigurationException('jsonservice_response_type_invalid',$id);
 +				}
 +				else
 +					throw new TConfigurationException('jsonservice_class_required',$id);	
 +			}
  		}
  		else
  			throw new THttpException(404,'jsonservice_provider_unknown',$id);
 diff --git a/framework/Web/Services/TPageService.php b/framework/Web/Services/TPageService.php index e35fb0e3..e4f9804c 100644 --- a/framework/Web/Services/TPageService.php +++ b/framework/Web/Services/TPageService.php @@ -69,6 +69,7 @@ Prado::using('System.Web.UI.TThemeManager');   * accessing to any resources.
   *
   * @author Qiang Xue <qiang.xue@gmail.com>
 + * @author Carl G. Mathisen <carlgmathisen@gmail.com>
   * @version $Id$
   * @package System.Web.Services
   * @since 3.0
 @@ -78,7 +79,11 @@ class TPageService extends TService  	/**
  	 * Configuration file name
  	 */
 -	const CONFIG_FILE='config.xml';
 +	const CONFIG_FILE_XML='config.xml';
 +	/**
 +	 * Configuration file name
 +	 */
 +	const CONFIG_FILE_PHP='config.php';
  	/**
  	 * Default base path
  	 */
 @@ -178,7 +183,7 @@ class TPageService extends TService  				$condition=$this->evaluateExpression($condition);
  			if($condition)
  			{
 -				if(($path=Prado::getPathOfNamespace($filePath,TApplication::CONFIG_FILE_EXT))===null || !is_file($path))
 +				if(($path=Prado::getPathOfNamespace($filePath,Prado::getApplication()->getConfigurationFileExt()))===null || !is_file($path))
  					throw new TConfigurationException('pageservice_includefile_invalid',$filePath);
  				$c=new TPageConfiguration($pagePath);
  				$c->loadFromFile($path,$configPagePath);
 @@ -213,7 +218,12 @@ class TPageService extends TService  		{
  			$pageConfig=new TPageConfiguration($pagePath);
  			if($config!==null)
 -				$pageConfig->loadPageConfigurationFromXml($config,$application->getBasePath(),'');
 +			{
 +				if($application->getConfigurationType()==TApplication::CONFIG_TYPE_PHP)
 +					$pageConfig->loadPageConfigurationFromPhp($config,$application->getBasePath(),'');
 +				else
 +					$pageConfig->loadPageConfigurationFromXml($config,$application->getBasePath(),'');
 +			}
  			$pageConfig->loadFromFiles($this->getBasePath());
  		}
  		else
 @@ -249,9 +259,12 @@ class TPageService extends TService  				$configCached=false;
  				$paths=explode('.',$pagePath);
  				$configPath=$this->getBasePath();
 +				$fileName = $this->getApplication()->getConfigurationType()==TApplication::CONFIG_TYPE_PHP
 +					? self::CONFIG_FILE_PHP
 +					: self::CONFIG_FILE_XML;
  				foreach($paths as $path)
  				{
 -					$configFile=$configPath.DIRECTORY_SEPARATOR.self::CONFIG_FILE;
 +					$configFile=$configPath.DIRECTORY_SEPARATOR.$fileName;
  					$currentTimestamp[$configFile]=@filemtime($configFile);
  					$configPath.=DIRECTORY_SEPARATOR.$path;
  				}
 @@ -262,7 +275,12 @@ class TPageService extends TService  			{
  				$pageConfig=new TPageConfiguration($pagePath);
  				if($config!==null)
 -					$pageConfig->loadPageConfigurationFromXml($config,$application->getBasePath(),'');
 +				{
 +					if($application->getConfigurationType()==TApplication::CONFIG_TYPE_PHP)
 +						$pageConfig->loadPageConfigurationFromPhp($config,$application->getBasePath(),'');
 +					else
 +						$pageConfig->loadPageConfigurationFromXml($config,$application->getBasePath(),'');
 +				}
  				$pageConfig->loadFromFiles($this->getBasePath());
  				$cache->set(self::CONFIG_CACHE_PREFIX.$this->getID().$pagePath,array($pageConfig,$currentTimestamp));
  			}
 @@ -581,16 +599,19 @@ class TPageConfiguration extends TComponent  		$page=array_pop($paths);
  		$path=$basePath;
  		$configPagePath='';
 +		$fileName = Prado::getApplication()->getConfigurationType()==TApplication::CONFIG_TYPE_PHP
 +			? TPageService::CONFIG_FILE_PHP
 +			: TPageService::CONFIG_FILE_XML;
  		foreach($paths as $p)
  		{
 -			$this->loadFromFile($path.DIRECTORY_SEPARATOR.TPageService::CONFIG_FILE,$configPagePath);
 +			$this->loadFromFile($path.DIRECTORY_SEPARATOR.$fileName,$configPagePath);
  			$path.=DIRECTORY_SEPARATOR.$p;
  			if($configPagePath==='')
  				$configPagePath=$p;
  			else
  				$configPagePath.='.'.$p;
  		}
 -		$this->loadFromFile($path.DIRECTORY_SEPARATOR.TPageService::CONFIG_FILE,$configPagePath);
 +		$this->loadFromFile($path.DIRECTORY_SEPARATOR.$fileName,$configPagePath);
  		$this->_rules=new TAuthorizationRuleCollection($this->_rules);
  	}
 @@ -604,11 +625,26 @@ class TPageConfiguration extends TComponent  		Prado::trace("Loading page configuration file $fname",'System.Web.Services.TPageService');
  		if(empty($fname) || !is_file($fname))
  			return;
 -		$dom=new TXmlDocument;
 -		if($dom->loadFromFile($fname))
 -			$this->loadFromXml($dom,dirname($fname),$configPagePath);
 +		
 +		if(Prado::getApplication()->getConfigurationType()==TApplication::CONFIG_TYPE_PHP)
 +		{
 +			$fcontent = include $fname;
 +			$this->loadFromPhp($fcontent,dirname($fname),$configPagePath);
 +		}
  		else
 -			throw new TConfigurationException('pageserviceconf_file_invalid',$fname);
 +		{	
 +			$dom=new TXmlDocument;
 +			if($dom->loadFromFile($fname))
 +				$this->loadFromXml($dom,dirname($fname),$configPagePath);
 +			else
 +				throw new TConfigurationException('pageserviceconf_file_invalid',$fname);
 +		}
 +	}
 +
 +	public function loadFromPhp($config,$configPath,$configPagePath)
 +	{
 +		$this->loadApplicationConfigurationFromPhp($config,$configPath);
 +		$this->loadPageConfigurationFromPhp($config,$configPath,$configPagePath);
  	}
  	/**
 @@ -624,6 +660,13 @@ class TPageConfiguration extends TComponent  		$this->loadApplicationConfigurationFromXml($dom,$configPath);
  		$this->loadPageConfigurationFromXml($dom,$configPath,$configPagePath);
  	}
 +	
 +	public function loadApplicationConfigurationFromPhp($config,$configPath)
 +	{
 +		$appConfig=new TApplicationConfiguration;
 +		$appConfig->loadFromPhp($config,$configPath);
 +		$this->_appConfigs[]=$appConfig;
 +	}
  	/**
  	 * Loads the configuration specific for application part
 @@ -637,6 +680,99 @@ class TPageConfiguration extends TComponent  		$this->_appConfigs[]=$appConfig;
  	}
 +	public function loadPageConfigurationFromPhp($config, $configPath, $configPagePath)
 +	{
 +		// authorization
 +		if(isset($config['authorization']) && is_array($config['authorization']))
 +		{
 +			$rules = array();
 +			foreach($config['authorization'] as $authorization)
 +			{
 +				$patterns=isset($authorization['pages'])?$authorization['pages']:'';
 +				$ruleApplies=false;
 +				if(empty($patterns) || trim($patterns)==='*') // null or empty string
 +					$ruleApplies=true;
 +				else
 +				{
 +					foreach(explode(',',$patterns) as $pattern)
 +					{
 +						if(($pattern=trim($pattern))!=='')
 +						{
 +							// we know $configPagePath and $this->_pagePath
 +							if($configPagePath!=='')  // prepend the pattern with ConfigPagePath
 +								$pattern=$configPagePath.'.'.$pattern;
 +							if(strcasecmp($pattern,$this->_pagePath)===0)
 +							{
 +								$ruleApplies=true;
 +								break;
 +							}
 +							if($pattern[strlen($pattern)-1]==='*') // try wildcard matching
 +							{
 +								if(strncasecmp($this->_pagePath,$pattern,strlen($pattern)-1)===0)
 +								{
 +									$ruleApplies=true;
 +									break;
 +								}
 +							}
 +						}
 +					}
 +				}
 +				if($ruleApplies)
 +				{
 +					$action = isset($authorization['action'])?$authorization['action']:'';
 +					$users = isset($authorization['users'])?$authorization['users']:'';
 +					$roles = isset($authorization['roles'])?$authorization['roles']:'';
 +					$verb = isset($authorization['verb'])?$authorization['verb']:'';
 +					$ips = isset($authorization['ips'])?$authorization['ips']:'';
 +					$rules[]=new TAuthorizationRule($action,$users,$roles,$verb,$ips);
 +				}
 +			}
 +			$this->_rules=array_merge($rules,$this->_rules);
 +		}
 +		// pages
 +		if(isset($config['pages']) && is_array($config['pages']))
 +		{
 +			if(isset($config['pages']['properties']))
 +			{
 +				$this->_properties = array_merge($this->_properties, $config['pages']['properties']);
 +				unset($config['pages']['properties']);
 +			}
 +			foreach($config['pages'] as $id => $page)
 +			{
 +				$properties = array();
 +				if(isset($page['properties']))
 +				{
 +					$properties=$page['properties'];
 +					unset($page['properties']);	
 +				}
 +				$matching=false;
 +				$id=($configPagePath==='')?$id:$configPagePath.'.'.$id;
 +				if(strcasecmp($id,$this->_pagePath)===0)
 +					$matching=true;
 +				else if($id[strlen($id)-1]==='*') // try wildcard matching
 +					$matching=strncasecmp($this->_pagePath,$id,strlen($id)-1)===0;
 +				if($matching)
 +					$this->_properties=array_merge($this->_properties,$properties);
 +			}
 +		}
 +		
 +		// external configurations
 +		if(isset($config['includes']) && is_array($config['includes']))
 +		{
 +			foreach($config['includes'] as $include)
 +			{
 +				$when = isset($include['when'])?true:false;
 +				if(!isset($include['file']))
 +					throw new TConfigurationException('pageserviceconf_includefile_required');
 +				$filePath = $include['file'];
 +				if(isset($this->_includes[$filePath]))
 +					$this->_includes[$filePath]=array($configPagePath,'('.$this->_includes[$filePath][1].') || ('.$when.')');
 +				else
 +					$this->_includes[$filePath]=array($configPagePath,$when);
 +			}
 +		}
 +	}
 +
  	/**
  	 * Loads the configuration specific for page service.
  	 * @param TXmlElement config xml element
 diff --git a/framework/Web/Services/TSoapService.php b/framework/Web/Services/TSoapService.php index d943d6fb..ddb5cecb 100644 --- a/framework/Web/Services/TSoapService.php +++ b/framework/Web/Services/TSoapService.php @@ -30,12 +30,16 @@   *     </service>   *   </services>   * </code> - * - * The above example specifies a single SOAP provider named "stockquote" - * whose class is "MyStockQuote". A SOAP client can then obtain the WSDL for - * this provider via the following URL: + * PHP configuration style:   * <code> - *   http://hostname/path/to/index.php?soap=stockquote.wsdl + *  'services' => array( + *    'soap' => array( + *     'class' => 'System.Web.Services.TSoapService' + *     'properties' => array( + *       'provider' => 'MyStockQuote' + *	   ) + *    ) + *  )   * </code>   *   * The WSDL for the provider class "MyStockQuote" is generated based on special @@ -79,13 +83,13 @@   *   * @author Knut Urdalen <knut.urdalen@gmail.com>   * @author Qiang Xue <qiang.xue@gmail.com> + * @author Carl G. Mathisen <carlgmathisen@gmail.com>   * @package System.Web.Services   * @since 3.1   */  class TSoapService extends TService  {  	const DEFAULT_SOAP_SERVER='TSoapServer'; -	const CONFIG_FILE_EXT='.xml';  	private $_servers=array();  	private $_configFile=null;  	private $_wsdlRequest=false; @@ -148,19 +152,35 @@ class TSoapService extends TService  	/**  	 * Loads configuration from an XML element -	 * @param TXmlElement configuration node +	 * @param mixed configuration node  	 * @throws TConfigurationException if soap server id is not specified or duplicated  	 */ -	private function loadConfig($xml) -	{ -		foreach($xml->getElementsByTagName('soap') as $serverXML) +	private function loadConfig($config) +	{	 +		if($this->getApplication()->getConfigurationType()==TApplication::CONFIG_TYPE_PHP)  		{ -			$properties=$serverXML->getAttributes(); -			if(($id=$properties->remove('id'))===null) -				throw new TConfigurationException('soapservice_serverid_required'); -			if(isset($this->_servers[$id])) -				throw new TConfigurationException('soapservice_serverid_duplicated',$id); -			$this->_servers[$id]=$properties; +			if(is_array($config)) +			{ +				foreach($config['soap'] as $id => $server) +				{ +					$properties = isset($server['properties'])?$server['properties']:array(); +					if(isset($this->_servers[$id])) +						throw new TConfigurationException('soapservice_serverid_duplicated',$id); +					$this->_servers[$id]=$properties; +				} +			} +		} +		else +		{ +			foreach($config->getElementsByTagName('soap') as $serverXML) +			{ +				$properties=$serverXML->getAttributes(); +				if(($id=$properties->remove('id'))===null) +					throw new TConfigurationException('soapservice_serverid_required'); +				if(isset($this->_servers[$id])) +					throw new TConfigurationException('soapservice_serverid_duplicated',$id); +				$this->_servers[$id]=$properties; +			}  		}  	} @@ -179,7 +199,7 @@ class TSoapService extends TService  	 */  	public function setConfigFile($value)  	{ -		if(($this->_configFile=Prado::getPathOfNamespace($value,self::CONFIG_FILE_EXT))===null) +		if(($this->_configFile=Prado::getPathOfNamespace($value,Prado::getApplication()->getConfigurationFileExt()))===null)  			throw new TConfigurationException('soapservice_configfile_invalid',$value);  	} @@ -221,7 +241,12 @@ class TSoapService extends TService  	protected function createServer()  	{  		$properties=$this->_servers[$this->_serverID]; -		if(($serverClass=$properties->remove('class'))===null) +		$serverClass=null; +		if($this->getApplication()->getConfigurationType()==TApplication::CONFIG_TYPE_PHP && isset($config['class'])) +			$serverClass=$config['class']; +		else if($this->getApplication()->getConfigurationType()==TApplication::CONFIG_TYPE_XML) +			$serverClass=$properties->remove('class'); +		if($serverClass===null)  			$serverClass=self::DEFAULT_SOAP_SERVER;  		Prado::using($serverClass);  		$className=($pos=strrpos($serverClass,'.'))!==false?substr($serverClass,$pos+1):$serverClass; diff --git a/framework/Web/TUrlMapping.php b/framework/Web/TUrlMapping.php index 47232401..09e45d99 100644 --- a/framework/Web/TUrlMapping.php +++ b/framework/Web/TUrlMapping.php @@ -70,10 +70,6 @@ Prado::using('System.Collections.TAttributeCollection');  class TUrlMapping extends TUrlManager
  {
  	/**
 -	 * File extension of external configuration file
 -	 */
 -	const CONFIG_FILE_EXT='.xml';
 -	/**
  	 * @var TUrlMappingPattern[] list of patterns.
  	 */
  	protected $_patterns=array();
 @@ -101,17 +97,17 @@ class TUrlMapping extends TUrlManager  	/**
  	 * Initializes this module.
  	 * This method is required by the IModule interface.
 -	 * @param TXmlElement configuration for this module, can be null
 +	 * @param mixed configuration for this module, can be null
  	 * @throws TConfigurationException if module is configured in the global scope.
  	 */
 -	public function init($xml)
 +	public function init($config)
  	{
 -		parent::init($xml);
 +		parent::init($config);
  		if($this->getRequest()->getRequestResolved())
  			throw new TConfigurationException('urlmapping_global_required');
  		if($this->_configFile!==null)
  			$this->loadConfigFile();
 -		$this->loadUrlMappings($xml);
 +		$this->loadUrlMappings($config);
  		if($this->_urlPrefix==='')
  			$this->_urlPrefix=$this->getRequest()->getApplicationUrl();
  		$this->_urlPrefix=rtrim($this->_urlPrefix,'/');
 @@ -125,9 +121,17 @@ class TUrlMapping extends TUrlManager  	{
  		if(is_file($this->_configFile))
   		{
 -			$dom=new TXmlDocument;
 -			$dom->loadFromFile($this->_configFile);
 -			$this->loadUrlMappings($dom);
 +			if($this->getApplication()->getConfigurationType()==TApplication::CONFIG_TYPE_PHP)
 +			{
 +				$config = include $this->_configFile;
 +				$this->loadUrlMappings($dom);
 +			}
 +			else
 +			{
 +				$dom=new TXmlDocument;
 +				$dom->loadFromFile($this->_configFile);
 +				$this->loadUrlMappings($dom);
 +			}
  		}
  		else
  			throw new TConfigurationException('urlmapping_configfile_inexistent',$this->_configFile);
 @@ -191,7 +195,7 @@ class TUrlMapping extends TUrlManager  	 */
  	public function setConfigFile($value)
  	{
 -		if(($this->_configFile=Prado::getPathOfNamespace($value,self::CONFIG_FILE_EXT))===null)
 +		if(($this->_configFile=Prado::getPathOfNamespace($value,$this->getApplication()->getConfigurationFileExt()))===null)
  			throw new TConfigurationException('urlmapping_configfile_invalid',$value);
  	}
 @@ -218,27 +222,51 @@ class TUrlMapping extends TUrlManager  	/**
  	 * Load and configure each url mapping pattern.
 -	 * @param TXmlElement configuration node
 +	 * @param mixed configuration node
  	 * @throws TConfigurationException if specific pattern class is invalid
  	 */
 -	protected function loadUrlMappings($xml)
 +	protected function loadUrlMappings($config)
  	{
 -		foreach($xml->getElementsByTagName('url') as $url)
 +		if(is_array($config))
  		{
 -			$properties=$url->getAttributes();
 -			if(($class=$properties->remove('class'))===null)
 -				$class=$this->getDefaultMappingClass();
 -			$pattern=Prado::createComponent($class,$this);
 -			if(!($pattern instanceof TUrlMappingPattern))
 -				throw new TConfigurationException('urlmapping_urlmappingpattern_required');
 -			foreach($properties as $name=>$value)
 -				$pattern->setSubproperty($name,$value);
 -			$this->_patterns[]=$pattern;
 -			$pattern->init($url);
 -
 -			$key=$pattern->getServiceID().':'.$pattern->getServiceParameter();
 -			$this->_constructRules[$key][]=$pattern;
 +			if(isset($config['urls']) && is_array($config['urls']))
 +			{
 +				foreach($config['urls'] as $url)
 +				{
 +					$class=null;
 +					if(!isset($url['class']))
 +						$class=$this->getDefaultMappingClass();
 +					$pattern=Prado::createComponent($class,$this);
 +					$properties = isset($url['properties'])?$url['properties']:array();
 +					$this->buildUrlMapping($class,$pattern,$properties,$url);
 +				}
 +			}
  		}
 +		else
 +		{
 +			foreach($config->getElementsByTagName('url') as $url)
 +			{
 +				$properties=$url->getAttributes();
 +				if(($class=$properties->remove('class'))===null)
 +					$class=$this->getDefaultMappingClass();
 +				$pattern=Prado::createComponent($class,$this);
 +				$this->buildUrlMapping($class,$pattern,$properties,$url);
 +			}
 +		}
 +	}
 +	
 +	private function buildUrlMapping($class, $pattern, $properties, $url)
 +	{
 +		$pattern=Prado::createComponent($class,$this);
 +		if(!($pattern instanceof TUrlMappingPattern))
 +			throw new TConfigurationException('urlmapping_urlmappingpattern_required');
 +		foreach($properties as $name=>$value)
 +			$pattern->setSubproperty($name,$value);
 +		$this->_patterns[]=$pattern;
 +		$pattern->init($url);
 +
 +		$key=$pattern->getServiceID().':'.$pattern->getServiceParameter();
 +		$this->_constructRules[$key][]=$pattern;
  	}
  	/**
 @@ -264,7 +292,7 @@ class TUrlMapping extends TUrlManager  					if(is_string($key))
  						$params[$key]=$value;
  				}
 -				if (!$pattern->getIsWildCardPattern()) +				if (!$pattern->getIsWildCardPattern())
  					$params[$pattern->getServiceID()]=$pattern->getServiceParameter();
  				return $params;
  			}
 @@ -450,11 +478,11 @@ class TUrlMappingPattern extends TComponent  	private $_caseSensitive=true;
 -	private $_isWildCardPattern=false; - -	private $_urlFormat=THttpRequestUrlFormat::Get; - -	private $_separator='/'; +	private $_isWildCardPattern=false;
 +
 +	private $_urlFormat=THttpRequestUrlFormat::Get;
 +
 +	private $_separator='/';
  	/**
  	 * Constructor.
 @@ -676,57 +704,57 @@ class TUrlMappingPattern extends TComponent  	}
  	/**
 -	 * @return boolean whether this pattern is a wildcard pattern +	 * @return boolean whether this pattern is a wildcard pattern
  	 * @since 3.1.4
  	 */
 -	public function getIsWildCardPattern() { -		return $this->_isWildCardPattern; -	} - -	/** -	 * @return THttpRequestUrlFormat the format of URLs. Defaults to THttpRequestUrlFormat::Get. -	 */ -	public function getUrlFormat() -	{ -		return $this->_urlFormat; -	} - -	/** -	 * Sets the format of URLs constructed and interpreted by this pattern. -	 * A Get URL format is like index.php?name1=value1&name2=value2 -	 * while a Path URL format is like index.php/name1/value1/name2/value. -	 * The separating character between name and value can be configured with  -	 * {@link setUrlParamSeparator} and defaults to '/'. -	 * Changing the UrlFormat will affect {@link constructUrl} and how GET variables -	 * are parsed. -	 * @param THttpRequestUrlFormat the format of URLs. -	 * @param since 3.1.4 -	 */ -	public function setUrlFormat($value) -	{ -		$this->_urlFormat=TPropertyValue::ensureEnum($value,'THttpRequestUrlFormat'); -	} - -	/** -	 * @return string separator used to separate GET variable name and value when URL format is Path. Defaults to slash '/'. -	 */ -	public function getUrlParamSeparator() -	{ -		return $this->_separator; -	} - -	/** -	 * @param string separator used to separate GET variable name and value when URL format is Path. -	 * @throws TInvalidDataValueException if the separator is not a single character -	 */ -	public function setUrlParamSeparator($value) -	{ -		if(strlen($value)===1) -			$this->_separator=$value; -		else -			throw new TInvalidDataValueException('httprequest_separator_invalid'); -	} - +	public function getIsWildCardPattern() {
 +		return $this->_isWildCardPattern;
 +	}
 +
 +	/**
 +	 * @return THttpRequestUrlFormat the format of URLs. Defaults to THttpRequestUrlFormat::Get.
 +	 */
 +	public function getUrlFormat()
 +	{
 +		return $this->_urlFormat;
 +	}
 +
 +	/**
 +	 * Sets the format of URLs constructed and interpreted by this pattern.
 +	 * A Get URL format is like index.php?name1=value1&name2=value2
 +	 * while a Path URL format is like index.php/name1/value1/name2/value.
 +	 * The separating character between name and value can be configured with 
 +	 * {@link setUrlParamSeparator} and defaults to '/'.
 +	 * Changing the UrlFormat will affect {@link constructUrl} and how GET variables
 +	 * are parsed.
 +	 * @param THttpRequestUrlFormat the format of URLs.
 +	 * @param since 3.1.4
 +	 */
 +	public function setUrlFormat($value)
 +	{
 +		$this->_urlFormat=TPropertyValue::ensureEnum($value,'THttpRequestUrlFormat');
 +	}
 +
 +	/**
 +	 * @return string separator used to separate GET variable name and value when URL format is Path. Defaults to slash '/'.
 +	 */
 +	public function getUrlParamSeparator()
 +	{
 +		return $this->_separator;
 +	}
 +
 +	/**
 +	 * @param string separator used to separate GET variable name and value when URL format is Path.
 +	 * @throws TInvalidDataValueException if the separator is not a single character
 +	 */
 +	public function setUrlParamSeparator($value)
 +	{
 +		if(strlen($value)===1)
 +			$this->_separator=$value;
 +		else
 +			throw new TInvalidDataValueException('httprequest_separator_invalid');
 +	}
 +
  	/**
  	 * @param array list of GET items to be put in the constructed URL
  	 * @return boolean whether this pattern IS the one for constructing the URL with the specified GET items.
 @@ -8,7 +8,7 @@  <body>  <h1>PRADO Framework for PHP 5 </h1> -<p>Version 3.1.6 to be released<br> +<p>Version 3.2 to be released<br>  Copyright© 2004-2009 by <a href="http://www.pradosoft.com/">Prado Software</a><br>  All Rights Reserved.  </p> | 
