summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--HISTORY4
-rw-r--r--UPGRADE5
-rwxr-xr-xbin/prado-cli.php2
-rw-r--r--build.xml12
-rw-r--r--buildscripts/classtree/build.php1
-rw-r--r--buildscripts/phing/tasks/PradoVersionTask.php15
-rw-r--r--buildscripts/texbuilder/quickstart/quickstart.tex2
-rw-r--r--composer.json19
-rw-r--r--composer.lock133
-rwxr-xr-xdemos/quickstart/protected/pages/Controls/Samples/TConditional/Home.page4
-rwxr-xr-xdemos/quickstart/protected/pages/Fundamentals/Components.page211
-rwxr-xr-xdemos/quickstart/protected/pages/GettingStarted/HelloWorld.page1
-rwxr-xr-xdemos/quickstart/protected/pages/GettingStarted/NewFeatures.page2
-rw-r--r--framework/PradoBase.php2
-rw-r--r--framework/Web/Javascripts/source/prado/prado.js2
-rw-r--r--framework/pradolite.php698
-rw-r--r--index.html2
17 files changed, 983 insertions, 132 deletions
diff --git a/HISTORY b/HISTORY
index cd478998..ef7b7d60 100644
--- a/HISTORY
+++ b/HISTORY
@@ -1,4 +1,4 @@
-Version 3.2.3 to be released
+Version 3.2.3 Nov 26, 2013
BUG: Issue #467 - TSafeHtml error on php 5.5 (ctrlaltca)
BUG: Issue #470 - Problem escaping characters in TActiveDropDownList (ctrlaltca)
@@ -18,7 +18,7 @@ EHN: Issue #260 - TComponent Update: Behaviors, Class Behaviors, fx global event
EHN: Issue #292 - Events should have priorities to allow event handler order to be specified (javalizard)
BUG: TDatePicker can't render css attributes class "datepicker_year_options" (m_rizki_r)
ENH: Added THtmlArea4 based on TinyMCE4 (ctrlaltca)
-
+BUG: TDatePicker renders a spurious TTextBox (ctrlaltca)
Version 3.2.2 Jul 20, 2013
diff --git a/UPGRADE b/UPGRADE
index 73a093bb..51f0304d 100644
--- a/UPGRADE
+++ b/UPGRADE
@@ -1,5 +1,5 @@
- Upgrading Instructions for PRADO Framework v3.2.2
+ Upgrading Instructions for PRADO Framework v3.2.3
=================================================
!!!IMPORTANT!!!
@@ -9,6 +9,9 @@ if you want to upgrade from version A to version C and there is
version B between A and C, you need to following the instructions
for both A and B.
+Upgrading from v3.2.2
+---------------------
+
Upgrading from v3.2.1
---------------------
- TEmailAddressValidator's CheckMXRecord property now defaults to false.
diff --git a/bin/prado-cli.php b/bin/prado-cli.php
index 4fa70c08..b4b43062 100755
--- a/bin/prado-cli.php
+++ b/bin/prado-cli.php
@@ -569,7 +569,7 @@ class PradoCommandLineUnitTest extends PradoCommandLineAction
if($match==null||($match!=null && $this->hasMatch($match,$entry)))
$test->addTestFile($path.'/'.$entry);
}
- if($entry!=='.' && $entry!=='..' && $entry!=='.svn' && is_dir($path.'/'.$entry) && $recursive)
+ if($entry!=='.' && $entry!=='..' && is_dir($path.'/'.$entry) && $recursive)
$this->addTests($test,$path.'/'.$entry,$recursive,$match);
}
closedir($dir);
diff --git a/build.xml b/build.xml
index 173db025..2255322b 100644
--- a/build.xml
+++ b/build.xml
@@ -37,7 +37,6 @@
All Source Files in framework
-->
<fileset dir="." id="framework">
- <exclude name="**/.svn"/>
<exclude name="**/*.bak"/>
<exclude name="**/*~"/>
<exclude name="**/pradolite.php"/><!-- will be generated -->
@@ -58,7 +57,6 @@
Surrounding files
-->
<fileset dir="." id="misc">
- <exclude name="**/.svn"/>
<exclude name="**/*.bak"/>
<exclude name="**/*~"/>
<include name="COPYRIGHT"/>
@@ -72,7 +70,6 @@
Documentation
-->
<fileset dir="." id="docs">
- <exclude name="**/.svn"/>
<exclude name="**/*.bak"/>
<exclude name="**/*~"/>
<exclude name="**/latex"/>
@@ -85,7 +82,6 @@
Demos
-->
<fileset dir="." id="demos">
- <exclude name="**/.svn"/>
<exclude name="**/*.bak"/>
<exclude name="**/*~"/>
<exclude name="**/runtime/*"/>
@@ -201,8 +197,6 @@
php="false"
templateconfig="buildscripts/apigen/pradosoft/config.neon"
/>
- <echo>Cleaning svn directories from API manuals...</echo>
- <delete dir="${build.doc.dir}/manual/resources/.svn" includeemptydirs="true" failonerror="true" />
<echo>Indexing API manuals...</echo>
<prado-api-index docdir="${build.doc.dir}/manual" todir="${build.doc.dir}/manual"/>
@@ -335,7 +329,6 @@
<echo>Checking php files..</echo>
<phplint deprecatedAsError="true">
<fileset dir="framework">
- <exclude name="**/.svn"/>
<exclude name="**/*.bak"/>
<exclude name="**/*~"/>
<include name="**/*.php"/>
@@ -345,7 +338,6 @@
<echo>Checking js files..</echo>
<jsllint>
<fileset dir="framework">
- <exclude name="**/.svn"/>
<exclude name="**/*.bak"/>
<exclude name="**/*~"/>
<include name="**/*.js"/>
@@ -355,7 +347,6 @@
<echo>Checking xml files..</echo>
<xmllint>
<fileset dir="framework">
- <exclude name="**/.svn"/>
<exclude name="**/*.bak"/>
<exclude name="**/*~"/>
<include name="**/*.xml"/>
@@ -367,7 +358,6 @@
<echo>Checking php files..</echo>
<phplint deprecatedAsError="true">
<fileset dir="demos">
- <exclude name="**/.svn"/>
<exclude name="**/*.bak"/>
<exclude name="**/*~"/>
<include name="**/*.php"/>
@@ -377,7 +367,6 @@
<echo>Checking js files..</echo>
<jsllint>
<fileset dir="demos">
- <exclude name="**/.svn"/>
<exclude name="**/*.bak"/>
<exclude name="**/*~"/>
<include name="**/*.js"/>
@@ -387,7 +376,6 @@
<echo>Checking xml files..</echo>
<xmllint>
<fileset dir="demos">
- <exclude name="**/.svn"/>
<exclude name="**/*.bak"/>
<exclude name="**/*~"/>
<include name="**/*.xml"/>
diff --git a/buildscripts/classtree/build.php b/buildscripts/classtree/build.php
index 44700be4..f7b8d7e7 100644
--- a/buildscripts/classtree/build.php
+++ b/buildscripts/classtree/build.php
@@ -12,7 +12,6 @@ $exclusions=array(
'pradolite.php',
'prado-cli.php',
'JSMin.php',
- '.svn',
'/I18N/core',
'/3rdParty',
'/Testing',
diff --git a/buildscripts/phing/tasks/PradoVersionTask.php b/buildscripts/phing/tasks/PradoVersionTask.php
index 4310cf60..15c73efd 100644
--- a/buildscripts/phing/tasks/PradoVersionTask.php
+++ b/buildscripts/phing/tasks/PradoVersionTask.php
@@ -38,17 +38,8 @@ class PradoVersionTask extends PropertyTask
*/
private function getPradoRevision()
{
- $svnPath=dirname(__FILE__).'/../../../.svn';
- if(is_file($svnPath.'/all-wcprops'))
- $propFile=$svnPath.'/all-wcprops';
- else if(is_file($svnPath.'/dir-wcprops'))
- $propFile=$svnPath.'/dir-wcprops';
- else
- return 'unknown';
- $contents=file_get_contents($propFile);
- if(preg_match('/\\/svn\\/\\!svn\\/ver\\/(\d+)\\//ms',$contents,$matches)>0)
- return $matches[1];
- else
- return 'unknown';
+ $rev=shell_exec("git log -1 --pretty=format:'%h'");
+ if($rev===null) $rev='unknown';
+ return $rev;
}
}
diff --git a/buildscripts/texbuilder/quickstart/quickstart.tex b/buildscripts/texbuilder/quickstart/quickstart.tex
index deaba73c..41258800 100644
--- a/buildscripts/texbuilder/quickstart/quickstart.tex
+++ b/buildscripts/texbuilder/quickstart/quickstart.tex
@@ -52,7 +52,7 @@
%----------------- TITLE --------------
-\title{\Huge \bfseries PRADO v3.2.2 Quickstart Tutorial
+\title{\Huge \bfseries PRADO v3.2.3 Quickstart Tutorial
\thanks{Copyright 2004-2013. All Rights Reserved.}
}
\author{Qiang Xue and Wei Zhuo}
diff --git a/composer.json b/composer.json
index 81573d01..26c41985 100644
--- a/composer.json
+++ b/composer.json
@@ -64,25 +64,6 @@
"ext-zlib" : "*"
},
"include-path": ["framework"],
- "autoload": {
- "psr-0" : {
- "Prado" : "framework",
- "Prado\\Caching" : "framework",
- "Prado\\Collections" : "framework",
- "Prado\\Exceptions" : "framework",
- "Prado\\I18N" : "framework",
- "Prado\\IO" : "framework",
- "Prado\\Security" : "framework",
- "Prado\\Util" : "framework",
- "Prado\\Web" : "framework",
- "Prado\\Web\\Javascripts" : "framework",
- "Prado\\Web\\Services" : "framework",
- "Prado\\Web\\UI" : "framework",
- "Prado\\Web\\UI\\ActiveControls" : "framework",
- "Prado\\Web\\UI\\WebControls" : "framework",
- "Prado\\Xml" : "framework"
- }
- },
"support" : {
"forum" : "http://www.pradosoft.com/forum",
"source" : "https://github.com/pradosoft/prado"
diff --git a/composer.lock b/composer.lock
index 4a907065..e9fd8533 100644
--- a/composer.lock
+++ b/composer.lock
@@ -3,7 +3,7 @@
"This file locks the dependencies of your project to a known state",
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file"
],
- "hash": "5d13e6a7e5d1c16086fabc64d066f227",
+ "hash": "16bb0dc37f5f9efa8c30a4538c6d3fba",
"packages": [
],
@@ -180,21 +180,21 @@
},
{
"name": "guzzle/guzzle",
- "version": "v3.7.3",
+ "version": "v3.7.4",
"source": {
"type": "git",
"url": "https://github.com/guzzle/guzzle.git",
- "reference": "0f16aad385528b5cf790392cb4a4d16cf600e944"
+ "reference": "b170b028c6bb5799640e46c8803015b0f9a45ed9"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/guzzle/guzzle/zipball/0f16aad385528b5cf790392cb4a4d16cf600e944",
- "reference": "0f16aad385528b5cf790392cb4a4d16cf600e944",
+ "url": "https://api.github.com/repos/guzzle/guzzle/zipball/b170b028c6bb5799640e46c8803015b0f9a45ed9",
+ "reference": "b170b028c6bb5799640e46c8803015b0f9a45ed9",
"shasum": ""
},
"require": {
"ext-curl": "*",
- "php": ">=5.3.2",
+ "php": ">=5.3.3",
"symfony/event-dispatcher": ">=2.1"
},
"replace": {
@@ -268,7 +268,7 @@
"rest",
"web service"
],
- "time": "2013-09-08 21:09:18"
+ "time": "2013-10-02 20:47:00"
},
{
"name": "kukulich/fshl",
@@ -314,16 +314,16 @@
},
{
"name": "nette/nette",
- "version": "v2.0.12",
+ "version": "v2.0.13",
"source": {
"type": "git",
"url": "https://github.com/nette/nette.git",
- "reference": "80a7e460badc3d71b1469bb23810ebf235b06b11"
+ "reference": "695f643c26c2326f08424fee138515fa286a0e07"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/nette/nette/zipball/80a7e460badc3d71b1469bb23810ebf235b06b11",
- "reference": "80a7e460badc3d71b1469bb23810ebf235b06b11",
+ "url": "https://api.github.com/repos/nette/nette/zipball/695f643c26c2326f08424fee138515fa286a0e07",
+ "reference": "695f643c26c2326f08424fee138515fa286a0e07",
"shasum": ""
},
"require": {
@@ -384,7 +384,7 @@
"neon",
"templating"
],
- "time": "2013-08-07 23:14:19"
+ "time": "2013-11-05 18:47:49"
},
{
"name": "phing/phing",
@@ -440,31 +440,32 @@
},
{
"name": "phpunit/dbunit",
- "version": "1.2.3",
+ "version": "1.3.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/dbunit.git",
- "reference": "8386782a2d55153e44a06eb1a9d13d6ed35d9c2d"
+ "reference": "9d8a28bdb41fbd3c0dc16fa32fc00862d06abace"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/dbunit/zipball/8386782a2d55153e44a06eb1a9d13d6ed35d9c2d",
- "reference": "8386782a2d55153e44a06eb1a9d13d6ed35d9c2d",
+ "url": "https://api.github.com/repos/sebastianbergmann/dbunit/zipball/9d8a28bdb41fbd3c0dc16fa32fc00862d06abace",
+ "reference": "9d8a28bdb41fbd3c0dc16fa32fc00862d06abace",
"shasum": ""
},
"require": {
"ext-pdo": "*",
"ext-simplexml": "*",
"php": ">=5.3.3",
- "phpunit/phpunit": ">=3.7.0@stable"
+ "phpunit/phpunit": ">=3.7.0@stable",
+ "symfony/yaml": ">=2.1.0"
},
"bin": [
- "dbunit.php"
+ "composer/bin/dbunit"
],
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.2.x-dev"
+ "dev-master": "1.3.x-dev"
}
},
"autoload": {
@@ -494,7 +495,7 @@
"testing",
"xunit"
],
- "time": "2013-03-01 11:50:46"
+ "time": "2013-11-04 08:33:33"
},
{
"name": "phpunit/php-code-coverage",
@@ -559,16 +560,16 @@
},
{
"name": "phpunit/php-file-iterator",
- "version": "1.3.3",
+ "version": "1.3.4",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-file-iterator.git",
- "reference": "16a78140ed2fc01b945cfa539665fadc6a038029"
+ "reference": "acd690379117b042d1c8af1fafd61bde001bf6bb"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/16a78140ed2fc01b945cfa539665fadc6a038029",
- "reference": "16a78140ed2fc01b945cfa539665fadc6a038029",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/acd690379117b042d1c8af1fafd61bde001bf6bb",
+ "reference": "acd690379117b042d1c8af1fafd61bde001bf6bb",
"shasum": ""
},
"require": {
@@ -595,12 +596,12 @@
}
],
"description": "FilterIterator implementation that filters files based on a list of suffixes.",
- "homepage": "http://www.phpunit.de/",
+ "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
"keywords": [
"filesystem",
"iterator"
],
- "time": "2012-10-11 11:44:38"
+ "time": "2013-10-10 15:34:57"
},
{
"name": "phpunit/php-invoker",
@@ -788,16 +789,16 @@
},
{
"name": "phpunit/phpunit",
- "version": "3.7.27",
+ "version": "3.7.28",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
- "reference": "4b024e753e3421837afbcca962c8724c58b39376"
+ "reference": "3b97c8492bcafbabe6b6fbd2ab35f2f04d932a8d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/4b024e753e3421837afbcca962c8724c58b39376",
- "reference": "4b024e753e3421837afbcca962c8724c58b39376",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/3b97c8492bcafbabe6b6fbd2ab35f2f04d932a8d",
+ "reference": "3b97c8492bcafbabe6b6fbd2ab35f2f04d932a8d",
"shasum": ""
},
"require": {
@@ -858,7 +859,7 @@
"testing",
"xunit"
],
- "time": "2013-09-16 03:09:52"
+ "time": "2013-10-17 07:27:40"
},
{
"name": "phpunit/phpunit-mock-objects",
@@ -911,16 +912,16 @@
},
{
"name": "phpunit/phpunit-selenium",
- "version": "1.3.2",
+ "version": "1.3.3",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit-selenium.git",
- "reference": "ba8ab98699dc07ede1b9e80a0523238cb5cec3d5"
+ "reference": "e89bfa1080dce9617c9b3e7760d50752974bfbd2"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/phpunit-selenium/zipball/ba8ab98699dc07ede1b9e80a0523238cb5cec3d5",
- "reference": "ba8ab98699dc07ede1b9e80a0523238cb5cec3d5",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit-selenium/zipball/e89bfa1080dce9617c9b3e7760d50752974bfbd2",
+ "reference": "e89bfa1080dce9617c9b3e7760d50752974bfbd2",
"shasum": ""
},
"require": {
@@ -961,7 +962,7 @@
"testing",
"xunit"
],
- "time": "2013-08-25 12:29:25"
+ "time": "2013-11-22 08:54:11"
},
{
"name": "phpunit/phpunit-story",
@@ -1121,17 +1122,17 @@
},
{
"name": "symfony/config",
- "version": "v2.3.4",
+ "version": "v2.3.7",
"target-dir": "Symfony/Component/Config",
"source": {
"type": "git",
"url": "https://github.com/symfony/Config.git",
- "reference": "65a927c15ca5a911ba2fa277a5457fa8129505b0"
+ "reference": "1ced3d6c88b22df8cd1fe5209dbd6a89df362a29"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/Config/zipball/65a927c15ca5a911ba2fa277a5457fa8129505b0",
- "reference": "65a927c15ca5a911ba2fa277a5457fa8129505b0",
+ "url": "https://api.github.com/repos/symfony/Config/zipball/1ced3d6c88b22df8cd1fe5209dbd6a89df362a29",
+ "reference": "1ced3d6c88b22df8cd1fe5209dbd6a89df362a29",
"shasum": ""
},
"require": {
@@ -1165,21 +1166,21 @@
],
"description": "Symfony Config Component",
"homepage": "http://symfony.com",
- "time": "2013-08-06 05:49:23"
+ "time": "2013-09-19 09:45:20"
},
{
"name": "symfony/console",
- "version": "v2.3.4",
+ "version": "v2.3.7",
"target-dir": "Symfony/Component/Console",
"source": {
"type": "git",
"url": "https://github.com/symfony/Console.git",
- "reference": "db78f8ff7fc9e28d25ff9a0bf6ddf9f0e35fbbe3"
+ "reference": "00848d3e13cf512e77c7498c2b3b0192f61f4b18"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/Console/zipball/db78f8ff7fc9e28d25ff9a0bf6ddf9f0e35fbbe3",
- "reference": "db78f8ff7fc9e28d25ff9a0bf6ddf9f0e35fbbe3",
+ "url": "https://api.github.com/repos/symfony/Console/zipball/00848d3e13cf512e77c7498c2b3b0192f61f4b18",
+ "reference": "00848d3e13cf512e77c7498c2b3b0192f61f4b18",
"shasum": ""
},
"require": {
@@ -1218,21 +1219,21 @@
],
"description": "Symfony Console Component",
"homepage": "http://symfony.com",
- "time": "2013-08-17 16:34:49"
+ "time": "2013-11-13 21:27:40"
},
{
"name": "symfony/event-dispatcher",
- "version": "v2.3.4",
+ "version": "v2.3.7",
"target-dir": "Symfony/Component/EventDispatcher",
"source": {
"type": "git",
"url": "https://github.com/symfony/EventDispatcher.git",
- "reference": "41c9826457c65fa3cf746f214985b7ca9cba42f8"
+ "reference": "2d8ece3c610726a73d0c95c885134efea182610e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/41c9826457c65fa3cf746f214985b7ca9cba42f8",
- "reference": "41c9826457c65fa3cf746f214985b7ca9cba42f8",
+ "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/2d8ece3c610726a73d0c95c885134efea182610e",
+ "reference": "2d8ece3c610726a73d0c95c885134efea182610e",
"shasum": ""
},
"require": {
@@ -1272,21 +1273,21 @@
],
"description": "Symfony EventDispatcher Component",
"homepage": "http://symfony.com",
- "time": "2013-07-21 12:12:18"
+ "time": "2013-10-13 06:32:10"
},
{
"name": "symfony/filesystem",
- "version": "v2.3.4",
+ "version": "v2.3.7",
"target-dir": "Symfony/Component/Filesystem",
"source": {
"type": "git",
"url": "https://github.com/symfony/Filesystem.git",
- "reference": "87acbbef6d35ba649f96f09cc572c45119b360c3"
+ "reference": "2b8995042086c5552c94d33b5553c492e9cfc00e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/Filesystem/zipball/87acbbef6d35ba649f96f09cc572c45119b360c3",
- "reference": "87acbbef6d35ba649f96f09cc572c45119b360c3",
+ "url": "https://api.github.com/repos/symfony/Filesystem/zipball/2b8995042086c5552c94d33b5553c492e9cfc00e",
+ "reference": "2b8995042086c5552c94d33b5553c492e9cfc00e",
"shasum": ""
},
"require": {
@@ -1319,21 +1320,21 @@
],
"description": "Symfony Filesystem Component",
"homepage": "http://symfony.com",
- "time": "2013-07-21 12:12:18"
+ "time": "2013-09-19 09:45:20"
},
{
"name": "symfony/stopwatch",
- "version": "v2.3.4",
+ "version": "v2.3.7",
"target-dir": "Symfony/Component/Stopwatch",
"source": {
"type": "git",
"url": "https://github.com/symfony/Stopwatch.git",
- "reference": "23333342d7edd461f576b246c6fa7b30b4d9bebe"
+ "reference": "2d3491564a1413ea98074c557491b73ae46294ac"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/Stopwatch/zipball/23333342d7edd461f576b246c6fa7b30b4d9bebe",
- "reference": "23333342d7edd461f576b246c6fa7b30b4d9bebe",
+ "url": "https://api.github.com/repos/symfony/Stopwatch/zipball/2d3491564a1413ea98074c557491b73ae46294ac",
+ "reference": "2d3491564a1413ea98074c557491b73ae46294ac",
"shasum": ""
},
"require": {
@@ -1366,21 +1367,21 @@
],
"description": "Symfony Stopwatch Component",
"homepage": "http://symfony.com",
- "time": "2013-07-21 12:12:18"
+ "time": "2013-10-17 11:48:01"
},
{
"name": "symfony/yaml",
- "version": "v2.3.4",
+ "version": "v2.3.7",
"target-dir": "Symfony/Component/Yaml",
"source": {
"type": "git",
"url": "https://github.com/symfony/Yaml.git",
- "reference": "5a279f1b5f5e1045a6c432354d9ea727ff3a9847"
+ "reference": "c1bda5b459d792cb253de12c65beba3040163b2b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/Yaml/zipball/5a279f1b5f5e1045a6c432354d9ea727ff3a9847",
- "reference": "5a279f1b5f5e1045a6c432354d9ea727ff3a9847",
+ "url": "https://api.github.com/repos/symfony/Yaml/zipball/c1bda5b459d792cb253de12c65beba3040163b2b",
+ "reference": "c1bda5b459d792cb253de12c65beba3040163b2b",
"shasum": ""
},
"require": {
@@ -1413,7 +1414,7 @@
],
"description": "Symfony Yaml Component",
"homepage": "http://symfony.com",
- "time": "2013-08-24 15:26:22"
+ "time": "2013-10-17 11:48:01"
}
],
"aliases": [
diff --git a/demos/quickstart/protected/pages/Controls/Samples/TConditional/Home.page b/demos/quickstart/protected/pages/Controls/Samples/TConditional/Home.page
index 9e37b675..5702970a 100755
--- a/demos/quickstart/protected/pages/Controls/Samples/TConditional/Home.page
+++ b/demos/quickstart/protected/pages/Controls/Samples/TConditional/Home.page
@@ -1,9 +1,9 @@
<com:TContent ID="body">
<h1>TConditional Samples</h1>
-<com:TConditional Condition="Prado::getVersion()==='3.2.2'">
+<com:TConditional Condition="Prado::getVersion()==='3.2.3'">
<prop:TrueTemplate>
- <com:TLabel Text="You are using PRADO 3.2.2" />
+ <com:TLabel Text="You are using PRADO 3.2.3" />
</prop:TrueTemplate>
<prop:FalseTemplate>
<com:TLabel Text="You are using PRADO <%= Prado::getVersion() %>" />
diff --git a/demos/quickstart/protected/pages/Fundamentals/Components.page b/demos/quickstart/protected/pages/Fundamentals/Components.page
index 9326d89c..11235b56 100755
--- a/demos/quickstart/protected/pages/Fundamentals/Components.page
+++ b/demos/quickstart/protected/pages/Fundamentals/Components.page
@@ -96,7 +96,216 @@ $button->OnClick->add( $callback );
$button->OnClick[] = $callback;
$button->attachEventHandler( 'OnClick' , $callback );
</com:TTextHighlighter>
-where <tt>$callback</tt> refers to a valid PHP callback (e.g. a function name, a class method <tt>array($object,'method')</tt>, etc.)
+</p>
+ The variable <tt>$callback</tt> contains the definition of the event handler that can be either a string referring to a global function name, or an array whose first element refers to an object and second element a method name/path that is reachable by the object, e.g.
+ </p>
+<ul>
+<li>'buttonClicked' : buttonClicked($sender,$param);</li>
+<li>array($object,'buttonClicked') : $object->buttonClicked($sender,$param);</li>
+<li>array($object,'MainContent.SubmitButton.buttonClicked') : $object->MainContent->SubmitButton->buttonClicked($sender,$param);</li>
+</ul>
+<com:SinceVersion Version="3.2.3" />
+<h2 id="26001">Global events</h2>
+<p id="130001" class="block-content">
+With the addition of behaviors, a more expansive event model is needed. There
+are two new event types (global and dynamic events) as well as a more comprehensive
+behavior model that includes class wide behaviors.
+</p>
+<p id="130002" class="block-content">
+A global event is defined by all events whose name starts with 'fx'.
+The event name is potentially a method name and is thus case-insensitive. All 'fx' events
+are valid as the whole 'fx' event/method space is global in nature. Any object may patch into
+any global event by defining that event as a method. Global events have priorities
+just like 'on' events; so as to be able to order the event execution. Due to the
+nature of all events which start with 'fx' being valid, in effect, every object
+has every 'fx' global event. It is simply an issue of tapping into the desired
+global event.
+</p>
+<p id="130003" class="block-content">
+A global event that starts with 'fx' can be called even if the object does not
+implement the method of the global event. A call to a non-existing 'fx' method
+will, at minimal, function and return null. If a method argument list has a first
+parameter, it will be returned instead of null. This allows filtering and chaining.
+'fx' methods do not automatically install and uninstall. To install and uninstall an
+object's global event listeners, call the object's <tt>listen</tt> and
+<tt>unlisten</tt> methods, respectively. An object may auto-install its global event
+during <tt>__construct</tt> by overriding <tt>getAutoGlobalListen</tt> and returning true.
+</p>
+<p id="130004" class="block-content">
+As of PHP version 5.3, nulled objects without code references will still continue to persist
+in the global event queue because <tt>__destruct</tt> is not automatically called. In the common
+__destruct method, if an object is listening to global events, then <tt>unlisten</tt> is called.
+<tt>unlisten</tt> is required to be manually called before an object is
+left without references if it is currently listening to any global events. This includes
+class wide behaviors.
+</p>
+<p id="130005" class="block-content">
+An object that contains a method that starts with 'fx' will have those functions
+automatically receive those events of the same name after <tt>listen</tt> is called on the object.
+</p>
+<p id="130006" class="block-content">
+An object may listen to a global event without defining an 'fx' method of the same name by
+adding an object method to the global event list. For example
+</p>
+<com:TTextHighlighter CssClass="source block-content">
+$component->fxGlobalCheck=$callback; // or $component->OnClick->add($callback);
+$component->attachEventHandler('fxGlobalCheck',array($object, 'someMethod'));
+</com:TTextHighlighter>
+<h2 id="26002">Events between Objects and their behaviors, Dynamic Events</h2>
+<p id="130007" class="block-content">
+An intra-object/behavior event is defined by methods that start with 'dy'. Just as with
+'fx' global events, every object has every dynamic event. Any call to a method that
+starts with 'dy' will be handled, regardless of whether it is implemented. These
+events are for communicating with attached behaviors.
+</p>
+<p id="130008" class="block-content">
+Dynamic events can be used in a variety of ways. They can be used to tell behaviors
+when a non-behavior method is called. Dynamic events could be used as data filters.
+They could also be used to specify when a piece of code is to be run, eg. should the
+loop process be performed on a particular piece of data. In this way, some control
+is handed to the behaviors over the process and/or data.
+</p>
+<p id="130009" class="block-content">
+If there are no handlers for an 'fx' or 'dy' event, it will return the first
+parameter of the argument list. If there are no arguments, these events
+will return null. If there are handlers an 'fx' method will be called directly
+within the object. Global 'fx' events are triggered by calling <tt>raiseEvent</tt>.
+For dynamic events where there are behaviors that respond to the dynamic events, a
+<tt>TCallChain</tt> is developed. A call chain allows the behavior dynamic event
+implementations to call further implementing behaviors within a chain.
+</p>
+<p id="130010" class="block-content">
+If an object implements <tt>IDynamicMethods</tt>, all global and object dynamic
+events will be sent to <tt>__dycall</tt>. In the case of global events, all
+global events will trigger this method. In the case of behaviors, all undefined
+dynamic events which are called will be passed through to this method.
+</p>
+<p id="130011" class="block-content">
+<h2 id="26003">Behaviors</h2>
+<p id="130012" class="block-content">
+There are two types of behaviors. There are individual object behaviors and
+there are class wide behaviors. Class behaviors depend upon object behaviors.
+</p>
+<p id="130013" class="block-content">
+When a new class implements <tt>IBehavior</tt> or <tt>IClassBehavior</tt> or
+extends <tt>TBehavior</tt> or <tt>TClassBehavior</tt>, it may be added to an
+object by calling the object's <tt>attachBehavior</tt>. The behaviors associated
+name can then be used to <tt>enableBehavior</tt> or <tt>disableBehavior</tt>
+the specific behavior.
+</p>
+<p id="130014" class="block-content">
+All behaviors may be turned on and off via <tt>enableBehaviors</tt> and
+<tt>disableBehaviors</tt>, respectively. To check if behaviors are on or off
+a call to <tt>getBehaviorsEnabled</tt> will provide the variable.
+</p>
+<p id="130015" class="block-content">
+Attaching and detaching whole sets of behaviors is done using
+<tt>attachBehaviors</tt> and <tt>detachBehaviors</tt>. <tt>clearBehaviors</tt>
+removes all of an object's behaviors.
+</p>
+<p id="130016" class="block-content">
+<tt>asa</tt> returns a behavior of a specific name. <tt>isa</tt> is the
+behavior inclusive function that acts as the PHP operator <tt>instanceof</tt>.
+A behavior could provide the functionality of a specific class thus causing
+the host object to act similarly to a completely different class. A behavior
+would then implement <tt>IInstanceCheck</tt> to provide the identity of the
+different class.
+</p>
+<p id="130017" class="block-content">
+Class behaviors are similar to object behaviors except that the class behavior
+is the implementation for all instances of the class. A class behavior
+will have the object upon which is being called be prepended to the parameter
+list. This way the object is known across the class behavior implementation.
+</p>
+<p id="130018" class="block-content">
+Class behaviors are attached using <tt>attachClassBehavior</tt> and detached
+using <tt>detachClassBehavior</tt>. Class behaviors are important in that
+they will be applied to all new instances of a particular class. In this way
+class behaviors become default behaviors to a new instances of a class in
+<tt>__construct</tt>. Detaching a class behavior will remove the behavior
+from the default set of behaviors created for an object when the object
+is instanced.
+</p>
+<p id="130019" class="block-content">
+Class behaviors are also added to all existing instances via the global 'fx'
+event mechanism. When a new class behavior is added, the event
+<tt>fxAttachClassBehavior</tt> is raised and all existing instances that are
+listening to this global event (primarily after <tt>listen</tt> is called)
+will have this new behavior attached. A similar process is used when
+detaching class behaviors. Any objects listening to the global 'fx' event
+<tt>fxDetachClassBehavior</tt> will have a class behavior removed.
+</p>
+<h2 id="26004">Dynamic Intra-Object Events</h2>
+<p id="130020" class="block-content">
+Dynamic events start with 'dy'. This mechanism is used to allow objects
+to communicate with their behaviors directly. The entire 'dy' event space
+is valid. All attached, enabled behaviors that implement a dynamic event
+are called when the host object calls the dynamic event. If there is no
+implementation or behaviors, this returns null when no parameters are
+supplied and will return the first parameter when there is at least one
+parameter in the dynamic event.
+</p>
+<com:TTextHighlighter CssClass="source block-content">
+ null == $this->dyBehaviorEvent();
+ 5 == $this->dyBehaviorEvent(5); //when no behaviors implement this dynamic event
+</com:TTextHighlighter>
+<p id="130021" class="block-content">
+Dynamic events can be chained together within behaviors to allow for data
+filtering. Dynamic events are implemented within behaviors by defining the
+event as a method.
+</p>
+<com:TTextHighlighter CssClass="source block-content">
+class TObjectBehavior extends TBehavior {
+ public function dyBehaviorEvent($param1, $callchain) {
+ //Do something, eg: $param1 += 13;
+ return $callchain->dyBehaviorEvent($param1);
+ }
+}
+</com:TTextHighlighter>
+<p id="130022" class="block-content">
+This implementation of a behavior and dynamic event will flow through to the
+next behavior implementing the dynamic event. The first parameter is always
+return when it is supplied. Otherwise a dynamic event returns null.
+</p>
+<p id="130023" class="block-content">
+In the case of a class behavior, the object is also prepended to the dynamic
+event.
+</p>
+<com:TTextHighlighter CssClass="source block-content">
+class TObjectClassBehavior extends TClassBehavior {
+ public function dyBehaviorEvent($hostobject, $param1, $callchain) {
+ //Do something, eg: $param1 += $hostobject->getNumber();
+ return $callchain->dyBehaviorEvent($param1);
+ }
+}
+</com:TTextHighlighter>
+</p>
+<p id="130024" class="block-content">
+When calling a dynamic event, only the parameters are passed. The host object
+and the call chain are built into the framework.
+</p>
+
+<h2 id="26005">Global Event and Dynamic event catching</h2>
+
+<p id="130025" class="block-content">
+Given that all global 'fx' events and dynamic 'dy' events are valid and
+operational, there is a mechanism for catching events called that are not
+implemented (similar to the built-in PHP method <tt>__call</tt>). When
+a dynamic or global event is called but a behavior does not implement it,
+yet desires to know when an undefined dynamic event is run, the behavior
+implements the interface <tt>IDynamicMethods</tt> and method <tt>__dycall</tt>.
+</p>
+<p id="130026" class="block-content">
+In the case of dynamic events, <tt>__dycall</tt> is supplied with the method
+name and its parameters. When a global event is raised, via <tt>raiseEvent</tt>,
+the method is the event name and the parameters are supplied.
+</p>
+<p id="130027" class="block-content">
+When implemented, this catch-all mechanism is called for event global event event
+when implemented outside of a behavior. Within a behavior, it will also be called
+when the object to which the behavior is attached calls any unimplemented dynamic
+event. This is the fall-back mechanism for informing a class and/or behavior
+of when an global and/or undefined dynamic event is executed.
</p>
<h2 id="704">Namespaces</h2>
diff --git a/demos/quickstart/protected/pages/GettingStarted/HelloWorld.page b/demos/quickstart/protected/pages/GettingStarted/HelloWorld.page
index c69921f8..557aa46d 100755
--- a/demos/quickstart/protected/pages/GettingStarted/HelloWorld.page
+++ b/demos/quickstart/protected/pages/GettingStarted/HelloWorld.page
@@ -60,6 +60,7 @@ $application->run(); // run the application
</li>
<li><tt>Home.php</tt> - page class for the <tt>Home</tt> page. It mainly contains the method responding to the <tt>OnClick</tt> event of the button.
<com:TTextHighlighter CssClass="source block-content" id="code_50005">
+<?php
class Home extends TPage
{
public function buttonClicked($sender,$param)
diff --git a/demos/quickstart/protected/pages/GettingStarted/NewFeatures.page b/demos/quickstart/protected/pages/GettingStarted/NewFeatures.page
index 897b45f0..95bcc57f 100755
--- a/demos/quickstart/protected/pages/GettingStarted/NewFeatures.page
+++ b/demos/quickstart/protected/pages/GettingStarted/NewFeatures.page
@@ -9,6 +9,8 @@ This page summarizes the main new features that are introduced in each PRADO rel
<h2 id="8001">Version 3.2.3</h2>
<ul>
<li>Added <a href="?page=Controls.HtmlArea4">THtmlArea4 control</a> based on TinyMCE4</li>
+<li>Added support for Behaviors, Class Behaviors, fx global events, and dy one to one events</li>
+<li>Added the ability to set a priority (order) to event handlers</li>
</ul>
<h2 id="8001">Version 3.2.2</h2>
diff --git a/framework/PradoBase.php b/framework/PradoBase.php
index 2da331c9..0722d0fd 100644
--- a/framework/PradoBase.php
+++ b/framework/PradoBase.php
@@ -71,7 +71,7 @@ class PradoBase
*/
public static function getVersion()
{
- return '3.2.2';
+ return '3.2.3';
}
/**
diff --git a/framework/Web/Javascripts/source/prado/prado.js b/framework/Web/Javascripts/source/prado/prado.js
index 59bf433b..2e3ffbaa 100644
--- a/framework/Web/Javascripts/source/prado/prado.js
+++ b/framework/Web/Javascripts/source/prado/prado.js
@@ -240,7 +240,7 @@ var Prado =
* Version of Prado clientscripts
* @var Version
*/
- Version: '3.2.2',
+ Version: '3.2.3',
/**
* Registry for Prado components
diff --git a/framework/pradolite.php b/framework/pradolite.php
index cc4bbb79..d9627d13 100644
--- a/framework/pradolite.php
+++ b/framework/pradolite.php
@@ -1,7 +1,7 @@
<?php
/**
* File Name: pradolite.php
- * Last Update: 2013/09/13 14:14:15
+ * Last Update: 2013/11/26 10:04:34
* Generated By: buildscripts/phpbuilder/build.php
*
* This file is used in lieu of prado.php to boost PRADO application performance.
@@ -25,7 +25,7 @@ class PradoBase
protected static $classExists = array();
public static function getVersion()
{
- return '3.2.2';
+ return '3.2.3';
}
public static function initErrorHandlers()
{
@@ -475,9 +475,9 @@ class TApplicationComponent extends TComponent
$fullPath=dirname($class->getFileName()).DIRECTORY_SEPARATOR.$assetPath;
return $this->publishFilePath($fullPath);
}
- public function publishFilePath($fullPath)
+ public function publishFilePath($fullPath, $checkTimestamp=false)
{
- return Prado::getApplication()->getAssetManager()->publishFilePath($fullPath);
+ return Prado::getApplication()->getAssetManager()->publishFilePath($fullPath, $checkTimestamp);
}
}
abstract class TModule extends TApplicationComponent implements IModule
@@ -1248,6 +1248,377 @@ class TTextWriter extends TComponent implements ITextWriter
$this->write($str."\n");
}
}
+class TPriorityList extends TList
+{
+ private $_d=array();
+ private $_o=false;
+ private $_fd=null;
+ private $_c=0;
+ private $_dp=10;
+ private $_p=8;
+ public function __construct($data=null,$readOnly=false,$defaultPriority=10,$precision=8)
+ {
+ parent::__construct();
+ if($data!==null)
+ $this->copyFrom($data);
+ $this->setReadOnly($readOnly);
+ $this->setPrecision($precision);
+ $this->setDefaultPriority($defaultPriority);
+ }
+ public function count()
+ {
+ return $this->getCount();
+ }
+ public function getCount()
+ {
+ return $this->_c;
+ }
+ public function getPriorityCount($priority=null)
+ {
+ if($priority===null)
+ $priority=$this->getDefaultPriority();
+ $priority=(string)round(TPropertyValue::ensureFloat($priority),$this->_p);
+ if(!isset($this->_d[$priority]) || !is_array($this->_d[$priority]))
+ return false;
+ return count($this->_d[$priority]);
+ }
+ public function getDefaultPriority()
+ {
+ return $this->_dp;
+ }
+ protected function setDefaultPriority($value)
+ {
+ $this->_dp=(string)round(TPropertyValue::ensureFloat($value),$this->_p);
+ }
+ public function getPrecision()
+ {
+ return $this->_p;
+ }
+ protected function setPrecision($value)
+ {
+ $this->_p=TPropertyValue::ensureInteger($value);
+ }
+ public function getIterator()
+ {
+ return new ArrayIterator($this->flattenPriorities());
+ }
+ public function getPriorities()
+ {
+ $this->sortPriorities();
+ return array_keys($this->_d);
+ }
+ protected function sortPriorities() {
+ if(!$this->_o) {
+ ksort($this->_d,SORT_NUMERIC);
+ $this->_o=true;
+ }
+ }
+ protected function flattenPriorities() {
+ if(is_array($this->_fd))
+ return $this->_fd;
+ $this->sortPriorities();
+ $this->_fd=array();
+ foreach($this->_d as $priority => $itemsatpriority)
+ $this->_fd=array_merge($this->_fd,$itemsatpriority);
+ return $this->_fd;
+ }
+ public function itemAt($index)
+ {
+ if($index>=0&&$index<$this->getCount()) {
+ $arr=$this->flattenPriorities();
+ return $arr[$index];
+ } else
+ throw new TInvalidDataValueException('list_index_invalid',$index);
+ }
+ public function itemsAtPriority($priority=null)
+ {
+ if($priority===null)
+ $priority=$this->getDefaultPriority();
+ $priority=(string)round(TPropertyValue::ensureFloat($priority),$this->_p);
+ return isset($this->_d[$priority])?$this->_d[$priority]:null;
+ }
+ public function itemAtIndexInPriority($index,$priority=null)
+ {
+ if($priority===null)
+ $priority=$this->getDefaultPriority();
+ $priority=(string)round(TPropertyValue::ensureFloat($priority), $this->_p);
+ return !isset($this->_d[$priority])?false:(
+ isset($this->_d[$priority][$index])?$this->_d[$priority][$index]:false
+ );
+ }
+ public function add($item,$priority=null)
+ {
+ if($this->getReadOnly())
+ throw new TInvalidOperationException('list_readonly',get_class($this));
+ return $this->insertAtIndexInPriority($item,false,$priority,true);
+ }
+ public function insertAt($index,$item)
+ {
+ if($this->getReadOnly())
+ throw new TInvalidOperationException('list_readonly',get_class($this));
+ if(($priority=$this->priorityAt($index,true))!==false)
+ $this->insertAtIndexInPriority($item,$priority[1],$priority[0]);
+ else
+ throw new TInvalidDataValueException('list_index_invalid',$index);
+ }
+ public function insertAtIndexInPriority($item,$index=false,$priority=null,$preserveCache=false)
+ {
+ if($this->getReadOnly())
+ throw new TInvalidOperationException('list_readonly',get_class($this));
+ if($priority===null)
+ $priority=$this->getDefaultPriority();
+ $priority=(string)round(TPropertyValue::ensureFloat($priority), $this->_p);
+ if($preserveCache) {
+ $this->sortPriorities();
+ $cc=0;
+ foreach($this->_d as $prioritykey=>$items)
+ if($prioritykey>=$priority)
+ break;
+ else
+ $cc+=count($items);
+ if($index===false&&isset($this->_d[$priority])) {
+ $c=count($this->_d[$priority]);
+ $c+=$cc;
+ $this->_d[$priority][]=$item;
+ } else if(isset($this->_d[$priority])) {
+ $c=$index+$cc;
+ array_splice($this->_d[$priority],$index,0,array($item));
+ } else {
+ $c = $cc;
+ $this->_o = false;
+ $this->_d[$priority]=array($item);
+ }
+ if($this->_fd&&is_array($this->_fd)) array_splice($this->_fd,$c,0,array($item));
+ } else {
+ $c=null;
+ if($index===false&&isset($this->_d[$priority])) {
+ $cc=count($this->_d[$priority]);
+ $this->_d[$priority][]=$item;
+ } else if(isset($this->_d[$priority])) {
+ $cc=$index;
+ array_splice($this->_d[$priority],$index,0,array($item));
+ } else {
+ $cc=0;
+ $this->_o=false;
+ $this->_d[$priority]=array($item);
+ }
+ if($this->_fd&&is_array($this->_fd)&&count($this->_d)==1)
+ array_splice($this->_fd,$cc,0,array($item));
+ else
+ $this->_fd=null;
+ }
+ $this->_c++;
+ return $c;
+ }
+ public function remove($item,$priority=false)
+ {
+ if($this->getReadOnly())
+ throw new TInvalidOperationException('list_readonly',get_class($this));
+ if(($p=$this->priorityOf($item,true))!==false)
+ {
+ if($priority!==false) {
+ if($priority===null)
+ $priority=$this->getDefaultPriority();
+ $priority=(string)round(TPropertyValue::ensureFloat($priority),$this->_p);
+ if($p[0]!=$priority)
+ throw new TInvalidDataValueException('list_item_inexistent');
+ }
+ $this->removeAtIndexInPriority($p[1],$p[0]);
+ return $p[2];
+ }
+ else
+ throw new TInvalidDataValueException('list_item_inexistent');
+ }
+ public function removeAt($index)
+ {
+ if($this->getReadOnly())
+ throw new TInvalidOperationException('list_readonly',get_class($this));
+ if(($priority=$this->priorityAt($index, true))!==false)
+ return $this->removeAtIndexInPriority($priority[1],$priority[0]);
+ throw new TInvalidDataValueException('list_index_invalid',$index);
+ }
+ public function removeAtIndexInPriority($index, $priority=null)
+ {
+ if($this->getReadOnly())
+ throw new TInvalidOperationException('list_readonly',get_class($this));
+ if($priority===null)
+ $priority=$this->getDefaultPriority();
+ $priority=(string)round(TPropertyValue::ensureFloat($priority),$this->_p);
+ if(!isset($this->_d[$priority])||$index<0||$index>=count($this->_d[$priority]))
+ throw new TInvalidDataValueException('list_item_inexistent');
+ $value=array_splice($this->_d[$priority],$index,1);
+ $value=$value[0];
+ if(!count($this->_d[$priority]))
+ unset($this->_d[$priority]);
+ $this->_c--;
+ $this->_fd=null;
+ return $value;
+ }
+ public function clear()
+ {
+ if($this->getReadOnly())
+ throw new TInvalidOperationException('list_readonly',get_class($this));
+ $d=array_reverse($this->_d,true);
+ foreach($this->_d as $priority=>$items) {
+ for($index=count($items)-1;$index>=0;$index--)
+ $this->removeAtIndexInPriority($index,$priority);
+ unset($this->_d[$priority]);
+ }
+ }
+ public function contains($item)
+ {
+ return $this->indexOf($item)>=0;
+ }
+ public function indexOf($item)
+ {
+ if(($index=array_search($item,$this->flattenPriorities(),true))===false)
+ return -1;
+ else
+ return $index;
+ }
+ public function priorityOf($item,$withindex = false)
+ {
+ $this->sortPriorities();
+ $absindex = 0;
+ foreach($this->_d as $priority=>$items) {
+ if(($index=array_search($item,$items,true))!==false) {
+ $absindex+=$index;
+ return $withindex?array($priority,$index,$absindex,
+ 'priority'=>$priority,'index'=>$index,'absindex'=>$absindex):$priority;
+ } else
+ $absindex+=count($items);
+ }
+ return false;
+ }
+ public function priorityAt($index,$withindex = false)
+ {
+ if($index<0||$index>=$this->getCount())
+ throw new TInvalidDataValueException('list_index_invalid',$index);
+ $absindex=$index;
+ $this->sortPriorities();
+ foreach($this->_d as $priority=>$items) {
+ if($index>=($c=count($items)))
+ $index-=$c;
+ else
+ return $withindex?array($priority,$index,$absindex,
+ 'priority'=>$priority,'index'=>$index,'absindex'=>$absindex):$priority;
+ }
+ return false;
+ }
+ public function insertBefore($indexitem, $item)
+ {
+ if($this->getReadOnly())
+ throw new TInvalidOperationException('list_readonly',get_class($this));
+ if(($priority=$this->priorityOf($indexitem,true))===false)
+ throw new TInvalidDataValueException('list_item_inexistent');
+ $this->insertAtIndexInPriority($item,$priority[1],$priority[0]);
+ return $priority[2];
+ }
+ public function insertAfter($indexitem, $item)
+ {
+ if($this->getReadOnly())
+ throw new TInvalidOperationException('list_readonly',get_class($this));
+ if(($priority=$this->priorityOf($indexitem,true))===false)
+ throw new TInvalidDataValueException('list_item_inexistent');
+ $this->insertAtIndexInPriority($item,$priority[1]+1,$priority[0]);
+ return $priority[2]+1;
+ }
+ public function toArray()
+ {
+ return $this->flattenPriorities();
+ }
+ public function toPriorityArray()
+ {
+ $this->sortPriorities();
+ return $this->_d;
+ }
+ public function toArrayBelowPriority($priority,$inclusive=false)
+ {
+ $this->sortPriorities();
+ $items=array();
+ foreach($this->_d as $itemspriority=>$itemsatpriority)
+ {
+ if((!$inclusive&&$itemspriority>=$priority)||$itemspriority>$priority)
+ break;
+ $items=array_merge($items,$itemsatpriority);
+ }
+ return $items;
+ }
+ public function toArrayAbovePriority($priority,$inclusive=true)
+ {
+ $this->sortPriorities();
+ $items=array();
+ foreach($this->_d as $itemspriority=>$itemsatpriority)
+ {
+ if((!$inclusive&&$itemspriority<=$priority)||$itemspriority<$priority)
+ continue;
+ $items=array_merge($items,$itemsatpriority);
+ }
+ return $items;
+ }
+ public function copyFrom($data)
+ {
+ if($data instanceof TPriorityList)
+ {
+ if($this->getCount()>0)
+ $this->clear();
+ foreach($data->getPriorities() as $priority)
+ {
+ foreach($data->itemsAtPriority($priority) as $index=>$item)
+ $this->insertAtIndexInPriority($item,$index,$priority);
+ }
+ } else if(is_array($data)||$data instanceof Traversable) {
+ if($this->getCount()>0)
+ $this->clear();
+ foreach($data as $key=>$item)
+ $this->add($item);
+ } else if($data!==null)
+ throw new TInvalidDataTypeException('map_data_not_iterable');
+ }
+ public function mergeWith($data)
+ {
+ if($data instanceof TPriorityList)
+ {
+ foreach($data->getPriorities() as $priority)
+ {
+ foreach($data->itemsAtPriority($priority) as $index=>$item)
+ $this->insertAtIndexInPriority($item,false,$priority);
+ }
+ }
+ else if(is_array($data)||$data instanceof Traversable)
+ {
+ foreach($data as $priority=>$item)
+ $this->add($item);
+ }
+ else if($data!==null)
+ throw new TInvalidDataTypeException('map_data_not_iterable');
+ }
+ public function offsetExists($offset)
+ {
+ return ($offset>=0&&$offset<$this->getCount());
+ }
+ public function offsetGet($offset)
+ {
+ return $this->itemAt($offset);
+ }
+ public function offsetSet($offset,$item)
+ {
+ if($offset===null)
+ return $this->add($item);
+ if($offset===$this->getCount()) {
+ $priority=$this->priorityAt($offset-1,true);
+ $priority[1]++;
+ } else {
+ $priority=$this->priorityAt($offset,true);
+ $this->removeAtIndexInPriority($priority[1],$priority[0]);
+ }
+ $this->insertAtIndexInPriority($item,$priority[1],$priority[0]);
+ }
+ public function offsetUnset($offset)
+ {
+ $this->removeAt($offset);
+ }
+}
class TMap extends TComponent implements IteratorAggregate,ArrayAccess,Countable
{
private $_d=array();
@@ -1392,6 +1763,310 @@ class TMapIterator implements Iterator
return $this->_key!==false;
}
}
+class TPriorityMap extends TMap
+{
+ private $_d=array();
+ private $_r=false;
+ private $_o=false;
+ private $_fd=null;
+ private $_c=0;
+ private $_dp=10;
+ private $_p=8;
+ public function __construct($data=null,$readOnly=false,$defaultPriority=10,$precision=8)
+ {
+ if($data!==null)
+ $this->copyFrom($data);
+ $this->setReadOnly($readOnly);
+ $this->setPrecision($precision);
+ $this->setDefaultPriority($defaultPriority);
+ }
+ public function getReadOnly()
+ {
+ return $this->_r;
+ }
+ protected function setReadOnly($value)
+ {
+ $this->_r=TPropertyValue::ensureBoolean($value);
+ }
+ public function getDefaultPriority()
+ {
+ return $this->_dp;
+ }
+ protected function setDefaultPriority($value)
+ {
+ $this->_dp = (string)round(TPropertyValue::ensureFloat($value), $this->_p);
+ }
+ public function getPrecision()
+ {
+ return $this->_p;
+ }
+ protected function setPrecision($value)
+ {
+ $this->_p=TPropertyValue::ensureInteger($value);
+ }
+ public function getIterator()
+ {
+ return new ArrayIterator($this->flattenPriorities());
+ }
+ protected function sortPriorities() {
+ if(!$this->_o) {
+ ksort($this->_d, SORT_NUMERIC);
+ $this->_o=true;
+ }
+ }
+ protected function flattenPriorities() {
+ if(is_array($this->_fd))
+ return $this->_fd;
+ $this->sortPriorities();
+ $this->_fd = array();
+ foreach($this->_d as $priority => $itemsatpriority)
+ $this->_fd = array_merge($this->_fd, $itemsatpriority);
+ return $this->_fd;
+ }
+ public function count()
+ {
+ return $this->getCount();
+ }
+ public function getCount()
+ {
+ return $this->_c;
+ }
+ public function getPriorityCount($priority=null)
+ {
+ if($priority===null)
+ $priority=$this->getDefaultPriority();
+ $priority=(string)round(TPropertyValue::ensureFloat($priority),$this->_p);
+ if(!isset($this->_d[$priority])||!is_array($this->_d[$priority]))
+ return false;
+ return count($this->_d[$priority]);
+ }
+ public function getPriorities()
+ {
+ $this->sortPriorities();
+ return array_keys($this->_d);
+ }
+ public function getKeys()
+ {
+ return array_keys($this->flattenPriorities());
+ }
+ public function itemAt($key,$priority=false)
+ {
+ if($priority===false){
+ $map=$this->flattenPriorities();
+ return isset($map[$key])?$map[$key]:null;
+ } else {
+ if($priority===null)
+ $priority=$this->getDefaultPriority();
+ $priority=(string)round(TPropertyValue::ensureFloat($priority),$this->_p);
+ return (isset($this->_d[$priority])&&isset($this->_d[$priority][$key]))?$this->_d[$priority][$key]:null;
+ }
+ }
+ public function setPriorityAt($key,$priority=null)
+ {
+ if($priority===null)
+ $priority=$this->getDefaultPriority();
+ $priority=(string)round(TPropertyValue::ensureFloat($priority),$this->_p);
+ $oldpriority=$this->priorityAt($key);
+ if($oldpriority!==false&&$oldpriority!=$priority) {
+ $value=$this->remove($key,$oldpriority);
+ $this->add($key,$value,$priority);
+ }
+ return $oldpriority;
+ }
+ public function itemsAtPriority($priority=null)
+ {
+ if($priority===null)
+ $priority=$this->getDefaultPriority();
+ $priority=(string)round(TPropertyValue::ensureFloat($priority),$this->_p);
+ return isset($this->_d[$priority])?$this->_d[$priority]:null;
+ }
+ public function priorityOf($item)
+ {
+ $this->sortPriorities();
+ foreach($this->_d as $priority=>$items)
+ if(($index=array_search($item,$items,true))!==false)
+ return $priority;
+ return false;
+ }
+ public function priorityAt($key)
+ {
+ $this->sortPriorities();
+ foreach($this->_d as $priority=>$items)
+ if(array_key_exists($key,$items))
+ return $priority;
+ return false;
+ }
+ public function add($key,$value,$priority=null)
+ {
+ if($priority===null)
+ $priority=$this->getDefaultPriority();
+ $priority=(string)round(TPropertyValue::ensureFloat($priority),$this->_p);
+ if(!$this->_r)
+ {
+ foreach($this->_d as $innerpriority=>$items)
+ if(array_key_exists($key,$items))
+ {
+ unset($this->_d[$innerpriority][$key]);
+ $this->_c--;
+ if(count($this->_d[$innerpriority])===0)
+ unset($this->_d[$innerpriority]);
+ }
+ if(!isset($this->_d[$priority])) {
+ $this->_d[$priority]=array($key=>$value);
+ $this->_o=false;
+ }
+ else
+ $this->_d[$priority][$key]=$value;
+ $this->_c++;
+ $this->_fd=null;
+ }
+ else
+ throw new TInvalidOperationException('map_readonly',get_class($this));
+ return $priority;
+ }
+ public function remove($key,$priority=false)
+ {
+ if(!$this->_r)
+ {
+ if($priority===null)
+ $priority=$this->getDefaultPriority();
+ if($priority===false)
+ {
+ $this->sortPriorities();
+ foreach($this->_d as $priority=>$items)
+ if(array_key_exists($key,$items))
+ {
+ $value=$this->_d[$priority][$key];
+ unset($this->_d[$priority][$key]);
+ $this->_c--;
+ if(count($this->_d[$priority])===0)
+ {
+ unset($this->_d[$priority]);
+ $this->_o=false;
+ }
+ $this->_fd=null;
+ return $value;
+ }
+ return null;
+ }
+ else
+ {
+ $priority=(string)round(TPropertyValue::ensureFloat($priority),$this->_p);
+ if(isset($this->_d[$priority])&&(isset($this->_d[$priority][$key])||array_key_exists($key,$this->_d[$priority])))
+ {
+ $value=$this->_d[$priority][$key];
+ unset($this->_d[$priority][$key]);
+ $this->_c--;
+ if(count($this->_d[$priority])===0) {
+ unset($this->_d[$priority]);
+ $this->_o=false;
+ }
+ $this->_fd=null;
+ return $value;
+ }
+ else
+ return null;
+ }
+ }
+ else
+ throw new TInvalidOperationException('map_readonly',get_class($this));
+ }
+ public function clear()
+ {
+ foreach($this->_d as $priority=>$items)
+ foreach(array_keys($items) as $key)
+ $this->remove($key);
+ }
+ public function contains($key)
+ {
+ $map=$this->flattenPriorities();
+ return isset($map[$key])||array_key_exists($key,$map);
+ }
+ public function toArray()
+ {
+ return $this->flattenPriorities();
+ }
+ public function toArrayBelowPriority($priority,$inclusive=false)
+ {
+ $this->sortPriorities();
+ $items=array();
+ foreach($this->_d as $itemspriority=>$itemsatpriority)
+ {
+ if((!$inclusive&&$itemspriority>=$priority)||$itemspriority>$priority)
+ break;
+ $items=array_merge($items,$itemsatpriority);
+ }
+ return $items;
+ }
+ public function toArrayAbovePriority($priority,$inclusive=true)
+ {
+ $this->sortPriorities();
+ $items=array();
+ foreach($this->_d as $itemspriority=>$itemsatpriority)
+ {
+ if((!$inclusive&&$itemspriority<=$priority)||$itemspriority<$priority)
+ continue;
+ $items=array_merge($items,$itemsatpriority);
+ }
+ return $items;
+ }
+ public function copyFrom($data)
+ {
+ if($data instanceof TPriorityMap)
+ {
+ if($this->getCount()>0)
+ $this->clear();
+ foreach($data->getPriorities() as $priority) {
+ foreach($data->itemsAtPriority($priority) as $key => $value) {
+ $this->add($key,$value,$priority);
+ }
+ }
+ }
+ else if(is_array($data)||$data instanceof Traversable)
+ {
+ if($this->getCount()>0)
+ $this->clear();
+ foreach($data as $key=>$value)
+ $this->add($key,$value);
+ }
+ else if($data!==null)
+ throw new TInvalidDataTypeException('map_data_not_iterable');
+ }
+ public function mergeWith($data)
+ {
+ if($data instanceof TPriorityMap)
+ {
+ foreach($data->getPriorities() as $priority)
+ {
+ foreach($data->itemsAtPriority($priority) as $key => $value)
+ $this->add($key,$value,$priority);
+ }
+ }
+ else if(is_array($data)||$data instanceof Traversable)
+ {
+ foreach($data as $key=>$value)
+ $this->add($key,$value);
+ }
+ else if($data!==null)
+ throw new TInvalidDataTypeException('map_data_not_iterable');
+ }
+ public function offsetExists($offset)
+ {
+ return $this->contains($offset);
+ }
+ public function offsetGet($offset)
+ {
+ return $this->itemAt($offset);
+ }
+ public function offsetSet($offset,$item)
+ {
+ $this->add($offset,$item);
+ }
+ public function offsetUnset($offset)
+ {
+ $this->remove($offset);
+ }
+}
class TStack extends TComponent implements IteratorAggregate,Countable
{
private $_d=array();
@@ -3767,7 +4442,7 @@ class TAttributeCollection extends TMap
}
public function hasProperty($name)
{
- return $this->contains($name) || parent::hasProperty($name);
+ return $this->contains($name) || parent::canGetProperty($name) || parent::canSetProperty($name);
}
public function canGetProperty($name)
{
@@ -6436,12 +7111,9 @@ class TClientScriptManager extends TApplicationComponent
public function getStyleSheetUrls()
{
$stylesheets = array_values(
- array_merge(
- array_map(
- create_function('$e', 'return is_array($e) ? $e[0] : $e;'),
- $this->_styleSheetFiles),
- $this->_styleSheets
- )
+ array_map(
+ create_function('$e', 'return is_array($e) ? $e[0] : $e;'),
+ $this->_styleSheetFiles)
);
foreach(Prado::getApplication()->getAssetManager()->getPublished() as $path=>$url)
if (substr($url,strlen($url)-4)=='.css')
@@ -6449,6 +7121,10 @@ class TClientScriptManager extends TApplicationComponent
$stylesheets = array_unique($stylesheets);
return $stylesheets;
}
+ public function getStyleSheetCodes()
+ {
+ return array_unique(array_values($this->_styleSheets));
+ }
public function registerHeadScriptFile($key,$url)
{
$this->checkIfNotInRender();
diff --git a/index.html b/index.html
index fadd51ca..37a2a60d 100644
--- a/index.html
+++ b/index.html
@@ -8,7 +8,7 @@
<body>
<h1>PRADO Framework for PHP 5 </h1>
-<p>Version 3.2.2<br>
+<p>Version 3.2.3<br>
Copyright&copy; 2004-2013 by <a href="http://www.pradosoft.com/">Prado Software</a><br>
All Rights Reserved.
</p>